|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r70137 - in sandbox/libpoet/trunk: . doc doc/boostbook doc/boostbook/html doc/javascript doc/javascript/nested_links doc/javascript/nested_links/css doc/javascript/nested_links/doc doc/javascript/nested_links/doc/xhtml doc/javascript/nested_links/doc/xhtml/images doc/javascript/nested_links/example doc/javascript/nested_links/example/boostbook_integration doc/javascript/nested_links/example/boostbook_integration/xhtml doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second doc/javascript/nested_links/example/simple doc/javascript/style_switcher doc/javascript/style_switcher/doc doc/style doc/style/html doc/style/html/conversion doc/style/html/images doc/style/html/images/admonitions doc/style/html/images/admonitions/solid doc/style/html/images/box_wrapper doc/style/html/images/box_wrapper/solid doc/style/html/images/callouts doc/style/html/images/footer doc/style/html/images/header doc/style/html/images/navigation doc/style/html/images/syntax doc/style/html/images/syntax/solid doc/style/html/syntax doc/style/pdf doc/style/pdf/images examples poet poet/detail test
From: fmhess_at_[hidden]
Date: 2011-03-18 16:01:39
Author: fmhess
Date: 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
New Revision: 70137
URL: http://svn.boost.org/trac/boost/changeset/70137
Log:
Imported libpoet code, almost the same as as it was at the
end of the old cvs repository.
Added:
sandbox/libpoet/trunk/
sandbox/libpoet/trunk/ChangeLog (contents, props changed)
sandbox/libpoet/trunk/LICENSE_1_0.txt (contents, props changed)
sandbox/libpoet/trunk/README (contents, props changed)
sandbox/libpoet/trunk/doc/
sandbox/libpoet/trunk/doc/boostbook/
sandbox/libpoet/trunk/doc/boostbook/HTML.manifest (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/Makefile (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/active_function_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/active_object_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/acyclic_mutex_base_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/acyclic_mutex_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/catalog.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/demo_locking_order_graph.png (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/exception_ptr_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/exceptions_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/future_barrier_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/future_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/future_select_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/html/
sandbox/libpoet/trunk/doc/boostbook/libpoet_doc.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/libpoet_reference.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/monitor_base_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/monitor_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/monitor_locks_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/monitor_ptr_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/mutex_grapher_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/boostbook/mutex_properties_hpp.xml (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/
sandbox/libpoet/trunk/doc/javascript/common.js (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/cookies.js (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/load_file.js (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/main.js (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/
sandbox/libpoet/trunk/doc/javascript/nested_links.js (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/css/
sandbox/libpoet/trunk/doc/javascript/nested_links/css/grouped_links.css (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/jamfile.v2 (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/nested_links.qbk (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/HTML.manifest (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/images/
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/images/grouped_links.png (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/index.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/example.qbk (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/jamfile.v2 (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/HTML.manifest (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/final.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/sub_b.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/sub_c.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second/sub_b.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/build_grouped_links.cpp (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/index.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/sections.xml (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/
sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/boost_libs.xml (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/simple.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/nested_links/index.html (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/style_switcher/
sandbox/libpoet/trunk/doc/javascript/style_switcher.js (contents, props changed)
sandbox/libpoet/trunk/doc/javascript/style_switcher/doc/
sandbox/libpoet/trunk/doc/javascript/style_switcher/doc/TODO (contents, props changed)
sandbox/libpoet/trunk/doc/style/
sandbox/libpoet/trunk/doc/style/html/
sandbox/libpoet/trunk/doc/style/html/blurbs.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/box_wrapper.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/callouts.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/conversion/
sandbox/libpoet/trunk/doc/style/html/conversion/boostbook_to_quickbook.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/conversion/html_to_quickbook.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/conversion/html_to_quickbook_general.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/conversion/quickbook_common.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/footer.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/general.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/header.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/headings.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/
sandbox/libpoet/trunk/doc/style/html/images/admonitions/
sandbox/libpoet/trunk/doc/style/html/images/admonitions/caution.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/important.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/note.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/
sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/caution.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/important.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/note.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/tip.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/warning.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/tip.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/admonitions/warning.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/bottom-left.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/bottom-right.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/bottom.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/bottom-left.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/bottom-right.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/bottom.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/top-left.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/top-right.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/top.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/top-left.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/top-right.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/top.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/
sandbox/libpoet/trunk/doc/style/html/images/callouts/1.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/10.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/11.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/12.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/13.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/14.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/15.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/2.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/3.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/4.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/5.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/6.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/7.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/8.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/callouts/9.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/footer/
sandbox/libpoet/trunk/doc/style/html/images/footer/background-left.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/footer/background-right.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/footer/background.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/header/
sandbox/libpoet/trunk/doc/style/html/images/header/background-more.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/header/background.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/header/flourish.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/navigation/
sandbox/libpoet/trunk/doc/style/html/images/navigation/home.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/navigation/next.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/navigation/prev.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/navigation/up.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/
sandbox/libpoet/trunk/doc/style/html/images/syntax/bc.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/cw.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/em.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/evening.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/kd.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/morning.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/sc.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/bc.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/cw.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/em.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/evening.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/kd.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/morning.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/sc.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/vim.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/vs.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/vim.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/images/syntax/vs.png (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/lists.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/main.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/nested_links.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/programlisting.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/spirit_nav.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/
sandbox/libpoet/trunk/doc/style/html/syntax.xml (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/bc.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/cw.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/em.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/evening.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/kd.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/morning.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/sc.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/vim.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/syntax/vs.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/table.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/html/toc.css (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/
sandbox/libpoet/trunk/doc/style/pdf/images/
sandbox/libpoet/trunk/doc/style/pdf/images/DangerGeneral.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/caution.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/home.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/important.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/next.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/note.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/prev.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/tip.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/tip2.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/up.svg (contents, props changed)
sandbox/libpoet/trunk/doc/style/pdf/images/warning.svg (contents, props changed)
sandbox/libpoet/trunk/examples/
sandbox/libpoet/trunk/examples/active_object_example.cpp (contents, props changed)
sandbox/libpoet/trunk/examples/acyclic_mutex_demo.cpp (contents, props changed)
sandbox/libpoet/trunk/examples/monitor_demo.cpp (contents, props changed)
sandbox/libpoet/trunk/examples/pipeline.cpp (contents, props changed)
sandbox/libpoet/trunk/examples/transform.cpp (contents, props changed)
sandbox/libpoet/trunk/make_release.sh (contents, props changed)
sandbox/libpoet/trunk/poet/
sandbox/libpoet/trunk/poet/active_function.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/active_object.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/acyclic_mutex.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/acyclic_mutex_base.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/
sandbox/libpoet/trunk/poet/detail/active_function_template.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/active_object.cpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/condition.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/event_queue.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/future_barrier_template.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/future_select_template.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/identity.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/monitor_base.ipp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/monitor_synchronizer.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/mutex_grapher.ipp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/mutex_grapher_decl.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/nonvoid.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/preprocessor_macros.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/template_static.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/detail/utility.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/exception_ptr.cpp (contents, props changed)
sandbox/libpoet/trunk/poet/exception_ptr.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/exceptions.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/future.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/future_barrier.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/future_select.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/monitor.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/monitor_base.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/monitor_locks.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/monitor_ptr.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/mutex_grapher.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/mutex_properties.hpp (contents, props changed)
sandbox/libpoet/trunk/poet/null_type.hpp (contents, props changed)
sandbox/libpoet/trunk/test/
sandbox/libpoet/trunk/test/Makefile (contents, props changed)
sandbox/libpoet/trunk/test/active_function_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/active_object_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/acyclic_mutex_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/acyclic_mutex_upgrade_lock_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/acyclic_shared_mutex_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/exception_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/future_combining_barrier_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/future_selector_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/future_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/future_void_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/future_waits_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/lazy_future_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/lock_move_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/monitor_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/new_mutex_api_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/not_default_constructible_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/promise_count_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/timed_join_test.cpp (contents, props changed)
sandbox/libpoet/trunk/test/undead_active_function_test.cpp (contents, props changed)
Added: sandbox/libpoet/trunk/ChangeLog
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/ChangeLog 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,1979 @@
+2009-05-11 16:00 tag v2009_05_11
+
+2009-05-11 16:00 fmhess
+
+ * doc/boostbook/: Makefile, libpoet_doc.xml: Updated dependencies.
+ We now depend on Signals2 from boost 1.39 instead of
+ thread_safe_signals.
+
+2009-03-30 11:49 fmhess
+
+ * test/Makefile: Updated my Makefile to deal with Signals2
+ inclusion into boost.
+
+2008-10-17 09:41 fmhess
+
+ * poet/detail/mutex_grapher_decl.hpp: Fixed some "static
+ initialization order fiasco" with mutex_grapher singletons.
+
+2008-10-01 22:09 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp: Added
+ some probably not really needed manual disconnections when
+ initial call of slot throws expired_slot.
+
+2008-10-01 21:57 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp: Went
+ back to throwing expired_slot for thread-safe slot
+ self-disconnection.
+
+2008-10-01 13:47 fmhess
+
+ * poet/active_function.hpp, poet/active_object.hpp,
+ poet/exception_ptr.cpp, poet/future.hpp, poet/future_barrier.hpp,
+ poet/future_select.hpp, poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, test/Makefile,
+ test/active_function_test.cpp: Ported from thread_safe_signals to
+ signals2 API. Docs still need some updating.
+
+2008-09-22 18:28 fmhess
+
+ * poet/monitor_locks.hpp: Added a workaround for msvc8 compiler bug
+
+2008-08-28 16:47 fmhess
+
+ * doc/boostbook/future_hpp.xml, poet/future.hpp: Tweaked
+ promise::fulfill to avoid ambiguous overload problems introduced
+ with recent support for implicit conversion from U to future<T>.
+
+2008-08-27 11:16 fmhess
+
+ * doc/boostbook/future_hpp.xml, poet/future.hpp: Added support for
+ implicit conversion from any type U to future<T> as long as U is
+ implicitly convertible to T.
+
+2008-06-25 10:44 tag v2008_06_25
+
+2008-06-25 10:44 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp,
+ detail/active_object.cpp: Added some inline keywords to fix
+ multiple definition problems.
+
+2008-06-19 10:14 tag v2008_06_19
+
+2008-06-19 10:14 fmhess
+
+ * ChangeLog: Updated ChangeLog with "cvs2cl -T"
+
+2008-06-18 16:48 fmhess
+
+ * poet/active_object.hpp, poet/future.hpp, poet/future_barrier.hpp,
+ poet/future_select.hpp, poet/detail/event_queue.hpp,
+ poet/detail/future_barrier_template.hpp,
+ test/active_function_test.cpp,
+ test/future_combining_barrier_test.cpp,
+ test/promise_count_test.cpp: Fixed some compile warnings/errors
+ on msvc9.
+
+2008-06-18 14:31 fmhess
+
+ * doc/boostbook/future_select_hpp.xml, poet/future_select.hpp: Got
+ rid of use of non-standard ssize_t.
+
+2008-06-18 12:36 fmhess
+
+ * doc/boostbook/active_function_hpp.xml, poet/active_function.hpp,
+ poet/detail/active_function_template.hpp,
+ test/active_function_test.cpp: Added support for default
+ constructing active_functions.
+
+2008-06-18 12:29 fmhess
+
+ * examples/active_object_example.cpp: Replaced
+ active_object_example.cpp with a new one that compiles after
+ recent changes, and is simpler.
+
+2008-06-18 11:39 fmhess
+
+ * doc/boostbook/future_select_hpp.xml: Added a mention of
+ future_selector thread-safety.
+
+2008-06-18 11:25 fmhess
+
+ * doc/boostbook/active_function_hpp.xml,
+ doc/boostbook/libpoet_doc.xml, examples/transform.cpp: Added
+ transform.cpp example.
+
+2008-06-18 11:12 fmhess
+
+ * examples/pipeline.cpp: Make use of std::plus and std::multiplies.
+
+2008-06-18 09:40 fmhess
+
+ * doc/boostbook/future_select_hpp.xml: Added documentation for
+ future_selector.
+
+2008-06-18 09:40 fmhess
+
+ * doc/boostbook/future_barrier_hpp.xml: Added documentation for
+ poet::null_type, and added a couple "purpose" elements.
+
+2008-06-17 15:20 fmhess
+
+ * poet/future_select.hpp, poet/detail/identity.hpp,
+ test/future_selector_test.cpp: Added test for and fixed overload
+ of future_selector::push. Added value_type typedef to
+ future_selector.
+
+2008-06-17 09:32 fmhess
+
+ * poet/: null_type.hpp, detail/nonvoid.hpp: Split poet::null_type
+ out of detail/nonvoid.hpp into its own header, since it will need
+ to be documented as part of the pubic interface.
+
+2008-06-17 09:23 fmhess
+
+ * doc/boostbook/: future_barrier_hpp.xml, future_select_hpp.xml:
+ Added documentation of FUTURE_BARRIER_MAX_ARGS and
+ FUTURE_SELECT_MAX_ARGS macros.
+
+2008-06-17 09:05 fmhess
+
+ * doc/boostbook/future_barrier_hpp.xml,
+ doc/boostbook/future_select_hpp.xml,
+ poet/detail/active_function_template.hpp,
+ poet/detail/future_barrier_template.hpp,
+ poet/detail/future_select_template.hpp,
+ test/future_combining_barrier_test.cpp: Decided to get rid of 1
+ argument future_barrier and future_select, which were only
+ provided to be consistent with future_combining_barrier. Renamed
+ some macros to differentiate them in future_barrier_template.hpp
+ and future_select_template.hpp.
+
+2008-06-16 15:48 fmhess
+
+ * doc/boostbook/future_barrier_hpp.xml: Added missing end para tag.
+
+2008-06-16 15:46 fmhess
+
+ * doc/boostbook/: future_barrier_hpp.xml, future_select_hpp.xml:
+ Added documentation for future_combining barrier. Corrected
+ documented names for future_barrier_range and
+ future_select_range.
+
+2008-06-16 14:01 fmhess
+
+ * doc/boostbook/future_hpp.xml: Added documentation for
+ promise::has_future, reset, and swap.
+
+2008-06-16 14:00 fmhess
+
+ * poet/future.hpp, test/promise_count_test.cpp: Fixed
+ promise<void>::has_future for void promise constructed from a
+ non-void promise.
+
+2008-06-16 11:56 fmhess
+
+ * doc/boostbook/active_function_hpp.xml: Removed mentions of guards
+ and wake from active_function documentation, as they no longer
+ exist.
+
+2008-06-16 10:59 fmhess
+
+ * doc/boostbook/active_object_hpp.xml: Updated active_object.hpp
+ documentation to reflect API changes caused by switchover to
+ waiting on futures for scheduling instead of relying on signals.
+
+2008-06-16 10:49 fmhess
+
+ * poet/active_object.hpp, poet/detail/active_object.cpp,
+ test/active_function_test.cpp: Got rid of now useless timeout
+ parameter of scheduler.
+
+2008-06-16 10:49 fmhess
+
+ * test/future_test.cpp: Expanded swap test very slightly.
+
+2008-06-16 09:35 fmhess
+
+ * doc/boostbook/future_hpp.xml: Added documentation for
+ future::join, swap, and default copy constructor and assignment
+ operators.
+
+2008-06-13 17:23 fmhess
+
+ * doc/boostbook/future_hpp.xml: Removed documentation for some
+ member functions which no longer exist.
+
+2008-06-12 16:34 fmhess
+
+ * poet/future.hpp, test/future_test.cpp: Added future::swap.
+
+2008-06-12 15:16 fmhess
+
+ * poet/future.hpp, poet/future_barrier.hpp,
+ poet/detail/future_barrier_template.hpp,
+ test/future_combining_barrier_test.cpp: Added some tests of
+ futures returned by future barriers properly throwing their
+ exceptions, and fixed problems they reported.
+
+2008-06-12 13:59 fmhess
+
+ * poet/future_barrier.hpp, poet/future_select.hpp,
+ test/future_waits_test.cpp: Added some tests for
+ future_select_range, future_barrier_range, and
+ future_combining_barrier_range for the case of an empty input
+ range, and fixed their behavior to pass tests.
+
+2008-06-12 11:54 fmhess
+
+ * poet/future.hpp, poet/future_barrier.hpp, poet/future_select.hpp,
+ test/Makefile, test/lazy_future_test.cpp: Disconnect
+ waiter_event_queue connections once they are no longer needed.
+ Added test for lazy evaluation behavior of future_select and
+ future_selector.
+
+2008-06-11 14:30 fmhess
+
+ * poet/future.hpp: Disconnect update connection for
+ future_body_proxy when observed future completes.
+
+2008-06-11 13:22 fmhess
+
+ * poet/: future.hpp, future_select.hpp: Added factory functions for
+ future_body<T> where its waiter_event_queue is now initialized.
+
+2008-06-11 11:44 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp:
+ Refactored setups of waiter_event_queues observing other
+ waiter_event_queues.
+
+2008-06-11 11:01 fmhess
+
+ * poet/: future_barrier.hpp, future_select.hpp: Did a little better
+ cleaning up connections as soon as they are no longer needed.
+
+2008-06-11 10:22 fmhess
+
+ * test/active_function_test.cpp: Fixed bug in test of
+ in_order_activation_queue.
+
+2008-06-11 10:18 fmhess
+
+ * poet/future.hpp, poet/future_select.hpp, test/future_test.cpp:
+ Fixed promise::fulfill when taking a lazy future argument
+
+2008-06-10 12:57 fmhess
+
+ * test/active_function_test.cpp: Added a new test for
+ active_function using in_order_activiation_queue (it currently
+ fails). Cleaned up output of active_function_test.
+
+2008-06-10 11:38 fmhess
+
+ * test/future_test.cpp: Added new test that exposes recently
+ introduced bug in promise::fulfill when argument is a future.
+
+2008-06-10 10:37 fmhess
+
+ * poet/future.hpp, test/future_test.cpp: Added test to
+ future_test.cpp and made it pass. Made future_test less verbose
+ in its output.
+
+2008-06-10 10:16 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp: Got rid
+ of get_weak_future_body by using make_weak.
+
+2008-06-10 10:15 fmhess
+
+ * poet/detail/utility.hpp: Added missing header include guard.
+
+2008-06-10 10:15 fmhess
+
+ * test/Makefile: Added target to run test programs in valgrind.
+
+2008-06-10 10:07 fmhess
+
+ * poet/future_select.hpp, poet/detail/utility.hpp,
+ test/future_selector_test.cpp: Implemented copy
+ construction/assignment for future_selector.
+
+2008-06-09 15:18 fmhess
+
+ * poet/future.hpp, test/future_waits_test.cpp: Removed
+ future::connect_update and future::cancel from the public
+ interface.
+
+2008-06-09 15:02 fmhess
+
+ * poet/active_function.hpp, poet/active_object.hpp,
+ poet/future.hpp, poet/future_select.hpp,
+ poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, test/active_function_test.cpp,
+ test/active_object_test.cpp, test/future_selector_test.cpp,
+ test/undead_active_function_test.cpp: Converted scheduler
+ entirely over to waiting on futures instead of relying on
+ completion signals. Simplified method
+ requests/scheduler/active_function by throwing out less useful
+ features that were difficult to implement cleanly with the new
+ scheme (guard functions, manual polling of scheduler,
+ cancellation of active_function method request through returned
+ future). Added promise::reset and swap. Added future::join.
+ Added future_selector::size, reset, and swap. Fixed logic bug in
+ future_selector::pop_selected.
+
+2008-06-09 14:51 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Updated links to active
+ object/monitor papers.
+
+2008-06-08 20:34 fmhess
+
+ * test/future_combining_barrier_test.cpp, poet/future_barrier.hpp,
+ poet/detail/future_barrier_template.hpp,
+ poet/detail/identity.hpp, test/future_waits_test.cpp: Added
+ ExceptionHandler parameter to future_combining_barrier, which
+ generates exception_ptr for returned future from exception_ptr of
+ input future.
+
+2008-06-05 16:52 fmhess
+
+ * poet/future_select.hpp, test/future_selector_test.cpp: Added new
+ test for future_selector regarding cancelling futures obtained
+ from a future_selector which no longer exists. Made changes so
+ test passes.
+
+2008-06-05 12:21 fmhess
+
+ * poet/active_function.hpp, poet/active_object.hpp,
+ poet/exception_ptr.cpp, poet/future.hpp, poet/future_barrier.hpp,
+ poet/future_select.hpp, poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, poet/detail/event_queue.hpp,
+ poet/detail/future_barrier_template.hpp, test/Makefile,
+ test/active_object_test.cpp,
+ test/future_combining_barrier_test.cpp,
+ test/future_selector_test.cpp: Added support for future_selector.
+ Futures now execute all user callback code in future-waiting
+ threads (type conversions and combiners from
+ future_combining_barrier). That means some futures are "lazy"
+ now, and will not emit their complete signals until waited
+ on/queried.
+
+2008-06-03 10:25 fmhess
+
+ * test/future_combining_barrier_test.cpp: Replaced convert with
+ identity.
+
+2008-06-02 15:46 fmhess
+
+ * test/: Makefile, future_combining_barrier_test.cpp: Added new
+ test program.
+
+2008-05-29 17:14 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp,
+ detail/future_barrier_template.hpp: Fixed problems with
+ thread-unsafe manual disconnects.
+
+2008-05-29 11:19 fmhess
+
+ * poet/future.hpp, test/promise_count_test.cpp: Added
+ promise::has_future (not yet documented).
+
+2008-05-29 10:41 fmhess
+
+ * poet/future.hpp, poet/future_barrier.hpp, poet/future_select.hpp,
+ poet/detail/future_barrier_template.hpp, poet/detail/nonvoid.hpp,
+ test/future_waits_test.cpp: Renamed poet::bogus_void to
+ poet::null_type. future_combining_barrier functions work now.
+ Dealt with explosion of friend classes to futures.
+
+2008-05-28 21:31 fmhess
+
+ * poet/detail/active_function_template.hpp: Fixed compile error
+ caused by last commit.
+
+2008-05-28 21:26 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp,
+ detail/active_function_template.hpp,
+ detail/future_barrier_template.hpp,
+ detail/preprocessor_macros.hpp: Added future_combining_barrier
+ free functions that accept heterogeneous input futures
+ (untested).
+
+2008-05-28 17:07 fmhess
+
+ * poet/: future.hpp, future_barrier.hpp, future_select.hpp,
+ detail/nonvoid.hpp: Using empty bogus_void class as place holder
+ for values from future<void>, instead of using int. Trying to
+ make some changes to handle future<void> specializations without
+ so much work.
+
+2008-05-28 16:03 fmhess
+
+ * poet/future.hpp, poet/future_barrier.hpp, poet/future_select.hpp,
+ poet/detail/nonvoid.hpp, test/future_waits_test.cpp:
+ future_combining_barrier_range seems to be working now.
+
+2008-05-27 13:13 fmhess
+
+ * doc/boostbook/Makefile, doc/boostbook/future_barrier_hpp.xml,
+ doc/boostbook/future_select_hpp.xml,
+ doc/boostbook/future_waits_hpp.xml,
+ doc/boostbook/libpoet_reference.xml, poet/future.hpp,
+ poet/future_barrier.hpp, poet/future_select.hpp,
+ poet/future_waits.hpp, poet/detail/future_barrier_template.hpp,
+ poet/detail/future_select_template.hpp,
+ poet/detail/future_waits_template.hpp: Split future_waits.hpp
+ into future_barrier.hpp and future_select.hpp. Added beginnings
+ of support for future barrier which takes a combiner function to
+ return a non-void return value.
+
+2008-05-27 11:17 fmhess
+
+ * doc/boostbook/future_waits_hpp.xml: Some more corrections for
+ updated future_select prototype.
+
+2008-05-27 09:55 fmhess
+
+ * poet/future_waits.hpp, test/future_waits_test.cpp: Fixed emission
+ of signals by composite futures produced by
+ future_barrier/future_select.
+
+2008-05-27 09:54 fmhess
+
+ * poet/future.hpp: Moved a condition::notify_all inside locked
+ section.
+
+2008-05-26 19:02 fmhess
+
+ * doc/boostbook/future_waits_hpp.xml: Updated with changes to
+ future_select prototype.
+
+2008-05-25 19:43 fmhess
+
+ * poet/future.hpp, poet/future_waits.hpp,
+ poet/detail/future_waits_template.hpp,
+ test/future_waits_test.cpp: Changed prototype of future_select to
+ take input future with a uniform type and return a future of the
+ same type, instead of accepting heterogeneous input futures and
+ returning a future<void>. Also renamed future_barrier and
+ future_select overloads that accept iteratotors to avoid
+ ambiguous overload problems. Still need to update documentation
+ to reflect changes.
+
+2008-05-23 18:47 fmhess
+
+ * poet/active_function.hpp: Resolved ambiguous overload problem
+ seen on msvc 9.
+
+2008-05-23 18:47 fmhess
+
+ * examples/active_object_example.cpp: Removed spurious typename.
+
+2008-05-23 17:57 fmhess
+
+ * test/timed_join_test.cpp: More unistd.h cleanup.
+
+2008-05-23 17:54 fmhess
+
+ * test/new_mutex_api_test.cpp: Catch lock error by const instead of
+ non-const reference.
+
+2008-05-23 17:52 fmhess
+
+ * poet/monitor_locks.hpp: Fixed compile error on msvc 9.
+
+2008-05-23 17:40 fmhess
+
+ * test/monitor_test.cpp: No __PRETTY_FUNCTION__ on msvc.
+
+2008-05-23 17:31 fmhess
+
+ * test/future_void_test.cpp: Fixed msvc compile warning.
+
+2008-05-23 17:29 fmhess
+
+ * test/: future_test.cpp, monitor_test.cpp, new_mutex_api_test.cpp,
+ timed_join_test.cpp, undead_active_function_test.cpp: Got rid of
+ more non-portable unistd.h usage.
+
+2008-05-23 17:17 fmhess
+
+ * poet/monitor_locks.hpp: Fixed compile error on msvc 9.
+
+2008-05-23 17:16 fmhess
+
+ * poet/monitor_ptr.hpp: Added private monitor_ptr::get_syncer
+ method which throws if _syncer member is null.
+
+2008-05-23 17:04 fmhess
+
+ * poet/detail/mutex_grapher.ipp: Fixed compile error due to lack of
+ __PRETTY_FUNCTION__ on msvc. Fixed msvc compile warning due to
+ unused parameter.
+
+2008-05-23 16:55 fmhess
+
+ * poet/detail/mutex_grapher.ipp: Removed include of stdint.h, which
+ doesn't seem to be used. If needed, use boost/stdint.hpp instead
+ since msvc does support stdint.h.
+
+2008-05-23 16:48 fmhess
+
+ * test/active_object_test.cpp: Got rid of unix-ism (unistd.h)
+
+2008-05-23 16:32 fmhess
+
+ * test/active_function_test.cpp: Removed unix-ism (unistd.h)
+
+2008-05-23 14:04 fmhess
+
+ * poet/detail/active_function_template.hpp: Fixed compile error
+ under msvc 9
+
+2008-05-23 14:03 fmhess
+
+ * poet/active_object.hpp: Fixed compiler warning under msvc 9.
+
+2008-05-23 12:50 fmhess
+
+ * poet/future_waits.hpp: Made future_select slightly more
+ efficient.
+
+2008-05-21 17:02 fmhess
+
+ * poet/: future_waits.hpp, detail/future_waits_template.hpp: Fixed
+ comments at tops of new future_waits files.
+
+2008-05-21 16:50 fmhess
+
+ * doc/boostbook/: future_hpp.xml, future_waits_hpp.xml,
+ libpoet_reference.xml: Added some minimal documentation on
+ future_barrier/future_select.
+
+2008-05-21 15:13 fmhess
+
+ * poet/future.hpp, poet/future_waits.hpp,
+ poet/detail/future_waits_template.hpp, test/Makefile,
+ test/future_waits_test.cpp: Added support for waiting on groups
+ of futures (future_barrier and future_select). No documentation
+ yet.
+
+2008-05-20 16:39 fmhess
+
+ * poet/future.hpp: Replaced some scoped_lock with unique_lock.
+
+2008-05-20 15:31 fmhess
+
+ * poet/future.hpp: Added detail::bogus_future_void_type typedef,
+ and fixed what appears to be a logic error in the template
+ assignment operator of future<void>.
+
+2008-05-20 14:41 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: A little tweaking of the note
+ on monitor_ptr's thread-safety.
+
+2008-05-20 14:41 fmhess
+
+ * doc/boostbook/active_function_hpp.xml: Documented the copy
+ semantics of active_function.
+
+2008-05-19 13:23 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Added note about monitor_ptr
+ thread safety.
+
+2008-05-16 15:13 fmhess
+
+ * doc/boostbook/future_hpp.xml, poet/future.hpp,
+ poet/detail/active_object.cpp, poet/detail/condition.hpp:
+ Replaced use of obsoleted boost::xtime with boost::system_time.
+
+2008-05-16 11:46 tag v2008_05_16
+
+2008-05-16 11:46 fmhess
+
+ * ChangeLog: Regenerated ChangeLog with "cvs2cl -T"
+
+2008-05-16 11:42 fmhess
+
+ * README: Made some minor updates to README.
+
+2008-05-16 11:15 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Fixed version date of lib
+ mentioned in docs.
+
+2008-05-15 16:22 fmhess
+
+ * examples/acyclic_mutex_demo.cpp: Updated acyclic_mutex example
+ code to boost.thread 1.35 api.
+
+2008-05-15 15:44 fmhess
+
+ * examples/monitor_demo.cpp: Updated monitor example code.
+
+2008-05-15 13:40 fmhess
+
+ * doc/boostbook/acyclic_mutex_hpp.xml: Updated acyclic_mutex docs
+ for boost.thread 1.35 api.
+
+2008-05-15 10:33 fmhess
+
+ * doc/boostbook/mutex_grapher_hpp.xml,
+ poet/detail/mutex_grapher_decl.hpp: Changed
+ mutex_grapher::scoped_lock to mutex_grapher::unique_lock, to
+ follow new boost.thread api.
+
+2008-05-15 10:32 fmhess
+
+ * doc/boostbook/acyclic_mutex_base_hpp.xml: Fixed link to
+ locking_order_graph typedef.
+
+2008-05-12 16:34 fmhess
+
+ * doc/boostbook/: monitor_hpp.xml, monitor_ptr_hpp.xml: Added
+ wrappers for Boost.Thread mutex concepts to synopsis of monitor
+ and monitor_ptr, and added some brief discussion of the concepts
+ in the class descriptions.
+
+2008-05-12 14:35 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, poet/monitor.hpp: Made
+ monitor::operator-> return a monitor_unique_lock instead of a
+ monitor_ptr. Updated monitor docs, including boost.thread 1.35
+ api and other changes.
+
+2008-05-12 13:21 fmhess
+
+ * test/Makefile: Need extra $ for shell variable to escape
+ makefile.
+
+2008-05-12 13:11 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml, poet/monitor_ptr.hpp: Got rid
+ of unneeded monitor_ptr::call_proxy, and instead use
+ monitor_unique_lock directly.
+
+2008-05-12 13:03 fmhess
+
+ * poet/monitor_locks.hpp: Need to call set_wait_function method
+ after move-constructing a lock.
+
+2008-05-12 11:00 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Updated monitor_ptr docs wrt
+ to changes to match boost.thread 1.35 api.
+
+2008-05-09 16:52 fmhess
+
+ * test/: Makefile, lock_move_test.cpp: Added lock_move_test.cpp
+
+2008-05-09 16:52 fmhess
+
+ * poet/monitor_locks.hpp: Fixed some subtle problems with
+ moving/swapping locks and their associated monitors.
+
+2008-05-09 10:24 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added docs for free swap and
+ move functions that take monitor locks as parameters.
+
+2008-05-09 09:11 fmhess
+
+ * poet/monitor_locks.hpp: Added monitor_type typedef to
+ monitor_upgrade_to_unique_lock.
+
+2008-05-08 15:52 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Tweaked lock constructor
+ descriptions.
+
+2008-05-08 15:39 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added documentation for
+ monitor_upgrade_to_unique_lock.
+
+2008-05-08 13:38 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added docs for
+ monitor_upgrade_lock.
+
+2008-05-08 11:26 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added default lock
+ constructors to documentation.
+
+2008-05-08 11:12 fmhess
+
+ * poet/monitor_locks.hpp: Added default lock constructors.
+
+2008-05-08 11:04 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added missing assignment
+ operator for monitor_unique_lock, and corrected a couple typos.
+ Added documentation for monitor_shared_lock.
+
+2008-04-24 11:40 fmhess
+
+ * test/new_mutex_api_test.cpp: Added a little test for non-boost
+ mutex with monitor_ptr and monitor_base
+
+2008-04-23 16:32 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Some updates to the front page of
+ the documentation.
+
+2008-04-23 16:31 fmhess
+
+ * doc/boostbook/monitor_hpp.xml: Used "copy-assignment" element to
+ document operator=, instead of "method" element. Added
+ documentation of additional assignment operator overload which
+ suppresses default assignment operator.
+
+2008-04-23 16:30 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Used "copy-assignment" element
+ to document assignment operator, instead of "method".
+
+2008-04-23 16:29 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added documentation for
+ monitor_unique_lock.
+
+2008-04-23 11:18 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Added monitor_ptr::swap
+ documentation, and sorted public member functions.
+
+2008-04-23 11:06 fmhess
+
+ * doc/boostbook/monitor_hpp.xml: Updated monitor swap
+ documentation. Sorted some method documentation entries by
+ method name.
+
+2008-04-23 09:56 fmhess
+
+ * poet/monitor_locks.hpp: Avoid potential conflicts with future
+ boost.thread revisions.
+
+2008-04-23 09:45 fmhess
+
+ * test/new_mutex_api_test.cpp: Made test of lock release a little
+ more complete.
+
+2008-04-23 08:57 fmhess
+
+ * poet/monitor_ptr.hpp, test/new_mutex_api_test.cpp: Throw
+ boost::lock_error if user attempts to use an empty monitor_ptr as
+ a mutex.
+
+2008-04-17 16:47 fmhess
+
+ * poet/monitor_locks.hpp: Reset monitor handle when releasing a
+ lock.
+
+2008-04-17 16:43 fmhess
+
+ * poet/monitor_locks.hpp, test/new_mutex_api_test.cpp: Added test
+ for lock release() method. Fixed bug with mutex() method not
+ returning NULL after release.
+
+2008-04-17 15:49 fmhess
+
+ * poet/monitor_locks.hpp, test/new_mutex_api_test.cpp: Added free
+ move functions.
+
+2008-04-17 14:12 fmhess
+
+ * poet/monitor_locks.hpp, test/new_mutex_api_test.cpp: Added free
+ swap functions for monitor locks. Added move/swap support to
+ monitor_upgrade_to_unique_lock.
+
+2008-04-17 11:36 fmhess
+
+ * test/new_mutex_api_test.cpp: Slightly expanded lock move tests to
+ excercise assignment operator.
+
+2008-04-16 17:01 fmhess
+
+ * poet/acyclic_mutex.hpp, poet/monitor.hpp, poet/monitor_locks.hpp,
+ poet/monitor_ptr.hpp, test/Makefile,
+ test/acyclic_mutex_upgrade_lock_test.cpp,
+ test/new_mutex_api_test.cpp: Added move support for monitor
+ locks. Fixed mutex() and release() methods for locks. Fixed
+ some problems with counts of a thread's upgrade/shared locks in
+ acyclic_mutex.
+
+2008-04-14 17:16 fmhess
+
+ * poet/acyclic_mutex.hpp, test/Makefile,
+ test/acyclic_mutex_upgrade_lock_test.cpp: Fixed some problems
+ with acyclic_mutex and upgrade locks.
+
+2008-04-14 11:27 fmhess
+
+ * poet/exception_ptr.cpp: Fixed static initialization problem with
+ s_bad_alloc.
+
+2008-04-13 19:19 fmhess
+
+ * poet/: monitor.hpp, monitor_locks.hpp, detail/utility.hpp: Made
+ monitor swap and assigment lock both monitors simultaneously,
+ which is possible safely without extra specializations now that
+ the base Lockable concept requires try locking.
+
+2008-04-13 16:00 fmhess
+
+ * poet/acyclic_mutex.hpp, poet/mutex_properties.hpp, test/Makefile,
+ test/acyclic_shared_mutex_test.cpp: Added support for wrapping
+ boost::shared_mutex in poet::acyclic_mutex.
+
+2008-04-12 14:53 fmhess
+
+ * poet/monitor.hpp, poet/monitor_locks.hpp, poet/monitor_ptr.hpp,
+ test/new_mutex_api_test.cpp: Added monitor_upgrade_lock and
+ monitor_upgrade_to_unique_lock. Restored fixed swap member
+ functions to monitor and monitor_ptr after Peter Dimov told me
+ why they were broken before.
+
+2008-04-11 16:50 fmhess
+
+ * poet/monitor_locks.hpp, poet/monitor_ptr.hpp,
+ test/new_mutex_api_test.cpp: Added implementation of
+ monitor_shared_lock.
+
+2008-04-10 15:56 fmhess
+
+ * poet/: acyclic_mutex.hpp, detail/mutex_grapher.ipp,
+ detail/mutex_grapher_decl.hpp: Ported acyclic_mutex to
+ boost.thread 1.35.0 api.
+
+2008-04-10 13:48 fmhess
+
+ * poet/monitor.hpp, test/new_mutex_api_test.cpp: Added support for
+ using monitor as mutex with boost.thread locks. Added some tests
+ for using boost.thread locks with monitor and monitor_ptr.
+
+2008-04-09 15:33 fmhess
+
+ * poet/monitor.hpp, poet/monitor_locks.hpp, poet/monitor_ptr.hpp,
+ test/Makefile, test/new_mutex_api_test.cpp: Made
+ monitor_unique_lock<monitor> work correctly. Added test for
+ monitor_unique_lock.
+
+2008-04-08 17:21 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, poet/monitor.hpp,
+ poet/monitor_locks.hpp, poet/monitor_ptr.hpp,
+ poet/detail/monitor_locks.hpp, test/Makefile: Added
+ poet::monitor_unique_lock to start moving towards new
+ Boost.Thread api. Converted monitor_ptr to use
+ monitor_unique_lock.
+
+2008-04-08 13:41 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, doc/boostbook/monitor_ptr_hpp.xml,
+ doc/boostbook/mutex_properties_hpp.xml, poet/acyclic_mutex.hpp,
+ poet/monitor.hpp, poet/monitor_ptr.hpp,
+ poet/mutex_properties.hpp, poet/detail/monitor_locks.hpp:
+ Compiles against boost.thread 1.35.0 now. Haven't updated API to
+ conform to changes in new boost.thread api yet.
+
+2008-04-07 15:03 fmhess
+
+ * poet/: monitor.hpp, monitor_base.hpp, monitor_ptr.hpp: Cleaned up
+ a lot of unnecessary specialized base classes of monitor and
+ monitor_ptr.
+
+2008-04-04 14:29 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, poet/monitor.hpp,
+ test/monitor_test.cpp: Added support for operator-> to
+ poet::monitor for convenience. Made
+ poet::monitor::get_monitor_ptr more const-correct.
+
+2008-03-25 16:28 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, doc/boostbook/monitor_ptr_hpp.xml,
+ poet/monitor.hpp, poet/monitor_ptr.hpp, test/monitor_test.cpp:
+ Added aliasing constructor/reset to monitor_ptr. Added
+ no-argument monitor_ptr::reset. Added
+ monitor::get_monitor_ptr(). Added swap overload for monitor_ptr.
+ Remove monitor::swap method from interface because it interfered
+ with argument dependent lookup for swap inside of monitor class.
+ Updated docs to reflect changes. Added tests for aliasing
+ constructor and swap.
+
+2008-01-28 11:49 fmhess
+
+ * README: Updated location of libpoet web site.
+
+2008-01-28 11:49 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: updated link to libpoet web site.
+
+2008-01-28 09:51 tag v2008_01_28
+
+2008-01-28 09:51 fmhess
+
+ * ChangeLog: Regenerated ChangeLog with "cvs2cl -T"
+
+2008-01-25 08:46 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Added a word.
+
+2008-01-23 10:18 fmhess
+
+ * poet/acyclic_mutex.hpp, poet/detail/mutex_grapher.ipp,
+ poet/detail/mutex_grapher_decl.hpp, test/acyclic_mutex_test.cpp:
+ Added support for disconnecting unused nodes in the locking order
+ graph and reusing them, to prevent unbounded growth of the
+ locking order graph when mutexes are continually created and
+ destroyed.
+
+2008-01-22 15:06 fmhess
+
+ * poet/monitor_ptr.hpp: Actually, the default copy constructor for
+ monitor_ptr was fine. Got rid of a bunch of unneeded
+ set_monitor_ptr() calls in monitor_ptr constructors.
+
+2008-01-22 14:58 fmhess
+
+ * poet/monitor.hpp, test/monitor_test.cpp: Fixed problem with
+ monitor default assignment operator getting used.
+
+2008-01-22 14:31 fmhess
+
+ * doc/boostbook/monitor_hpp.xml: Fixed monitor docs with respect to
+ wrapped object (not) needing to be copy-constructible.
+
+2008-01-22 14:13 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, doc/boostbook/monitor_ptr_hpp.xml,
+ poet/monitor.hpp, poet/monitor_ptr.hpp, test/monitor_test.cpp:
+ Made copy constructors for monitor and monitor_ptr take const
+ references. Fixed some problems with default copy constructors
+ getting called.
+
+2008-01-22 13:29 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, poet/monitor.hpp,
+ test/monitor_test.cpp: Made poet::monitor assignment operator
+ take a const reference. Got rid of pointless overload.
+
+2008-01-22 12:22 fmhess
+
+ * doc/boostbook/monitor_hpp.xml: Added documentation for new
+ templated poet::monitor constructors.
+
+2008-01-22 11:43 fmhess
+
+ * poet/monitor.hpp, poet/monitor_ptr.hpp,
+ poet/detail/active_function_template.hpp,
+ poet/detail/preprocessor_macros.hpp, test/acyclic_mutex_test.cpp,
+ test/monitor_test.cpp: Added support for forwarding poet::monitor
+ constructor arguments to constructor for its templated value
+ type.
+
+2008-01-21 19:57 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Used "returns" elements
+ instead of "description" for monitor_ptr comparison operators.
+
+2008-01-21 19:25 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Added docs for monitor_ptr
+ cast and comparison functions.
+
+2008-01-21 19:24 fmhess
+
+ * poet/monitor_ptr.hpp: Allow comparison operators to be applied to
+ two monitor_ptr with different mutex types.
+
+2008-01-21 17:44 fmhess
+
+ * poet/monitor_ptr.hpp, test/monitor_test.cpp: Added support for
+ static/dynamic/const_pointer_cast to poet::monitor_ptr.
+
+2008-01-15 16:21 fmhess
+
+ * doc/boostbook/libpoet_doc.xml, poet/monitor.hpp,
+ poet/monitor_ptr.hpp, poet/detail/mutex_grapher.ipp,
+ poet/detail/mutex_grapher_decl.hpp: Updated some copyright
+ notices with year 2008
+
+2008-01-14 11:59 fmhess
+
+ * poet/monitor.hpp, poet/monitor_ptr.hpp, test/monitor_test.cpp:
+ Added const overloads to make const monitor and monitor_ptr
+ objects useable. Fixed monitor::scoped_timed_lock constructor to
+ take timeout.
+
+2007-12-31 13:28 tag v2007_12_31
+
+2007-12-31 13:28 fmhess
+
+ * ChangeLog: Added ChangeLog, generated with "cvs2cl -T"
+
+2007-12-31 13:13 fmhess
+
+ * doc/boostbook/mutex_grapher_hpp.xml: mutex_grapher mutex isn't
+ recursive any more.
+
+2007-12-31 13:10 fmhess
+
+ * poet/detail/: mutex_grapher.ipp, mutex_grapher_decl.hpp: Run user
+ cycle handler with no locks held, to eliminate chance of deadlock
+ with user's code. Mutex for mutex_grapher doesn't need to be
+ recursive any more.
+
+2007-12-31 11:21 fmhess
+
+ * poet/monitor_ptr.hpp, test/monitor_test.cpp: Made comparisons of
+ monitor_ptr work.
+
+2007-12-21 14:08 fmhess
+
+ * poet/mutex_properties.hpp: Leave mutex_properties as an
+ incomplete type.
+
+2007-12-21 12:28 fmhess
+
+ * test/: Makefile, monitor_test.cpp: Added test program for monitor
+ and monitor_ptr.
+
+2007-12-21 12:21 fmhess
+
+ * poet/monitor.hpp: Added missing include.
+
+2007-12-21 12:02 fmhess
+
+ * test/: Makefile, acyclic_mutex_test.cpp: Added test for
+ acyclic_mutex.
+
+2007-12-20 17:50 fmhess
+
+ * doc/boostbook/monitor_hpp.xml: Updated docs for changes to
+ monitor::swap.
+
+2007-12-20 16:27 fmhess
+
+ * poet/: future.hpp, monitor.hpp: Use koenig lookup for swap()
+ calls. Moved overload of std::swap (illegal) into poet
+ namespace.
+
+2007-12-20 15:58 fmhess
+
+ * doc/boostbook/: libpoet_doc.xml, monitor_hpp.xml: Some minor
+ documentation tweaks.
+
+2007-12-19 16:48 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, poet/monitor.hpp: Added
+ specialization of std::swap for monitor class.
+
+2007-12-19 15:44 fmhess
+
+ * poet/monitor.hpp: Used std::swap<T> to (possibly) optimize
+ monitor assignment.
+
+2007-12-19 15:18 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Added some caveats
+
+2007-12-19 14:51 fmhess
+
+ * doc/boostbook/mutex_grapher_hpp.xml: Added link to example
+ program and acyclic_mutex to mutex_grapher description.
+
+2007-12-19 14:51 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Slight expansion of status
+ section.
+
+2007-12-19 14:38 fmhess
+
+ * doc/boostbook/: Makefile, demo_locking_order_graph.png,
+ libpoet_doc.xml: Added png of graphviz file produced by acyclic
+ mutex example program.
+
+2007-12-19 14:05 fmhess
+
+ * doc/boostbook/Makefile, doc/boostbook/acyclic_mutex_base_hpp.xml,
+ doc/boostbook/acyclic_mutex_hpp.xml,
+ doc/boostbook/libpoet_doc.xml,
+ doc/boostbook/libpoet_reference.xml,
+ doc/boostbook/mutex_grapher_hpp.xml,
+ examples/acyclic_mutex_demo.cpp: Added initial documentation for
+ acyclic_mutex and friends.
+
+2007-12-19 14:05 fmhess
+
+ * poet/detail/: mutex_grapher.ipp, mutex_grapher_decl.hpp: Label
+ vertices for default constructed acyclic_mutexes as "mutex N"
+ instead of "vertex N". Added some needed quoting to graphviz
+ output file.
+
+2007-12-19 14:02 fmhess
+
+ * examples/monitor_demo.cpp: Added some comments describing example
+ and copyright header
+
+2007-12-19 14:00 fmhess
+
+ * poet/monitor.hpp: Adding a default constructor to monitor class
+ shouldn't cause any problems.
+
+2007-12-19 13:46 fmhess
+
+ * poet/detail/: mutex_grapher.ipp, mutex_grapher_decl.hpp: Renamed
+ private, non-const overload of mutex_grapher::locked_mutexes() to
+ internal_locked_mutexes() to avoid compilation error.
+
+2007-12-19 09:53 fmhess
+
+ * poet/detail/: mutex_grapher.ipp, mutex_grapher_decl.hpp: Made
+ mutex_grapher::write_graphviz() const
+
+2007-12-18 10:45 fmhess
+
+ * poet/detail/mutex_grapher_decl.hpp: Made mutex_grapher
+ noncopyable for good measure.
+
+2007-12-17 15:53 fmhess
+
+ * poet/: acyclic_mutex_base.hpp, detail/mutex_grapher.ipp: Renamed
+ acyclic_mutex_base::vertex_descriptor() method to just vertex().
+
+2007-12-17 14:56 fmhess
+
+ * poet/: acyclic_mutex.hpp, acyclic_mutex_base.hpp: Made
+ acyclic_mutex::node_key() and
+ acyclic_mutex_base::vertex_descriptor() methods return
+ boost::optional<>s instead of pointers.
+
+2007-12-17 14:14 fmhess
+
+ * poet/acyclic_mutex.hpp: Renamed acyclic_mutex::wrapped_mutex_type
+ to mutex_type, for better consistency with monitor/monitor_ptr
+ classes.
+
+2007-12-14 17:18 fmhess
+
+ * doc/boostbook/mutex_properties_hpp.xml: Use "purpose" elements
+ instead of "description" for static-constants, since boostbook
+ doesn't generate anything for descriptions.
+
+2007-12-14 15:21 fmhess
+
+ * doc/boostbook/: Makefile, libpoet_reference.xml,
+ mutex_properties_hpp.xml: Added some documentation for
+ mutex_properties template.
+
+2007-12-14 15:12 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Removed some obsolete
+ references to try/timed monitors.
+
+2007-12-14 14:21 fmhess
+
+ * doc/boostbook/monitor_hpp.xml: Updated monitor docs to reflect
+ dropping of try_monitor and timed_monitor.
+
+2007-12-14 14:21 fmhess
+
+ * doc/boostbook/active_function_hpp.xml: Removed some useless
+ "classname" elements.
+
+2007-12-14 13:33 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Updated monitor_ptr
+ documentation to reflect dropping of try_monitor_ptr and
+ timed_monitor_ptr.
+
+2007-12-14 13:33 fmhess
+
+ * doc/boostbook/monitor_locks_hpp.xml: Added an entry for scoped
+ lock destructor.
+
+2007-12-13 13:49 fmhess
+
+ * poet/: acyclic_mutex.hpp, acyclic_mutex_base.hpp,
+ detail/acyclic_mutex_base.hpp, detail/mutex_grapher.ipp,
+ detail/mutex_grapher_decl.hpp: Moved acyclic_mutex_base out of
+ detail namespace. Got rid of acyclic_mutex_keyed_base. Added
+ public mutex_grapher::mutex_list().
+
+2007-12-13 12:04 fmhess
+
+ * poet/: acyclic_mutex.hpp, mutex_properties.hpp,
+ detail/acyclic_mutex_base.hpp, detail/mutex_grapher.ipp,
+ detail/mutex_grapher_decl.hpp: Added support for recursive
+ mutexes as the template type parameter of acyclic_mutex.
+
+2007-12-12 17:10 fmhess
+
+ * poet/: acyclic_mutex.hpp, mutex_grapher.hpp,
+ detail/acyclic_mutex_base.hpp, detail/mutex_grapher.ipp,
+ detail/mutex_grapher_decl.hpp: Made templating of Key and
+ KeyCompare types for acyclic mutexes actually work. Brought
+ detail/mutex_grapher_decl.hpp back from the dead to resolve a
+ circular header dependency.
+
+2007-12-11 16:23 fmhess
+
+ * poet/acyclic_mutex.hpp: Condensed acyclic_mutex,
+ try_acyclic_mutex, and timed_acyclic_mutex into a single
+ acyclic_mutex class by using partial template specialization and
+ mutex_properties<>.
+
+2007-12-09 17:48 fmhess
+
+ * poet/: monitor.hpp, monitor_base.hpp, monitor_ptr.hpp,
+ detail/monitor_locks.hpp: Condensed monitor_ptr, try_monitor_ptr,
+ and timed_monitor_ptr into a single monitor_ptr class.
+
+2007-12-09 16:52 fmhess
+
+ * poet/: monitor.hpp, mutex_properties.hpp: Collapsed monitor,
+ try_monitor, and timed_monitor into a single monitor class with
+ the magic of new mutex_properties<> class, and partial template
+ specialization.
+
+2007-12-05 13:27 fmhess
+
+ * doc/boostbook/: libpoet_doc.xml, monitor_base_hpp.xml: Added
+ mention of poet::monitor where only poet::monitor_ptr was
+ mentioned before.
+
+2007-12-05 11:50 fmhess
+
+ * examples/monitor_demo.cpp, doc/boostbook/monitor_hpp.xml: Added
+ example of using poet::monitor to monitor_demo.cpp.
+
+2007-12-05 11:18 fmhess
+
+ * doc/boostbook/: Makefile, libpoet_reference.xml: Split reference
+ section into subsections.
+
+2007-12-05 10:57 fmhess
+
+ * doc/boostbook/monitor_hpp.xml, poet/monitor.hpp: Made monitor
+ destructor virtual. Made try_monitor::scoped_try_lock and
+ timed_monitor::scoped_timed_lock constructors more particular
+ about their parameter.
+
+2007-12-05 10:55 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Added "see also" sections to
+ monitor_ptr descriptions.
+
+2007-12-05 10:36 fmhess
+
+ * doc/boostbook/: monitor_hpp.xml, monitor_locks_hpp.xml: Updated
+ docs for monitor to reflect split into
+ monitor/try_monitor/timed_monitor
+
+2007-12-04 16:48 fmhess
+
+ * poet/: mutex_grapher.hpp, detail/mutex_grapher.ipp: Wrapped
+ mutex_grapher singleton in a monitor_ptr, accessible only though
+ mutex_grapher::scoped_lock objects. Made default cycle handler
+ print out a message to stderr before aborting.
+
+2007-12-04 15:59 fmhess
+
+ * poet/detail/monitor_locks.hpp: Gave up on trying to clear
+ synchronizer's wait function on unlock for now, since it will
+ break with recursive mutexes.
+
+2007-12-04 09:37 fmhess
+
+ * poet/detail/monitor_locks.hpp: Crash cleanly (or whatever happens
+ when you try to call a null boost::function) if user code for a
+ monitor object attempts to wait() without being locked. Fixed
+ comments describing monitor_locks.hpp.
+
+2007-12-01 23:28 fmhess
+
+ * poet/monitor.hpp: Simplified monitor/try_monitor/timed_monitor
+ implementation by realizing they can all use plain monitor_ptr.
+
+2007-12-01 21:19 fmhess
+
+ * poet/monitor.hpp: Split off poet::try_monitor and
+ poet::timed_monitor variants off from poet::monitor.
+
+2007-12-01 18:56 fmhess
+
+ * poet/detail/monitor_locks.hpp: Made monitor scoped locks keep
+ shared_ptr for value instead of raw pointer, to be safe agains
+ locks outliving the monitor_ptr they were made from.
+
+2007-12-01 13:34 fmhess
+
+ * doc/boostbook/active_object_hpp.xml, poet/active_object.hpp,
+ poet/detail/active_object.cpp: Reworked how
+ out_of_order_activation_queue works, so it scales better with
+ number of pending requests.
+
+2007-11-30 17:54 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Added documentation of
+ monitor_ptr::reset(), and for changes to one of the constructors.
+
+2007-11-30 17:25 fmhess
+
+ * doc/boostbook/: Makefile, libpoet_reference.xml, monitor_hpp.xml,
+ monitor_locks_hpp.xml, monitor_ptr_hpp.xml: Reworked docs for
+ scoped locks so they are closer to reality. Added docs for
+ poet::monitor.
+
+2007-11-30 17:05 fmhess
+
+ * poet/: monitor.hpp, monitor_ptr.hpp, detail/monitor_locks.hpp:
+ Moved scoped locks into their own file
+ (detail/monitor_locks.hpp). Fixed assignment to a
+ default-constructed monitor. Made monitor assignment operator
+ and copy constructor take non-const references when copying from
+ other monitors, since they lock their arguments before copying
+ out their values. Fixed crash in monitor_ptr::reset(). Added
+ conversion to bool for monitor_ptr.
+
+2007-11-30 17:02 fmhess
+
+ * poet/monitor_base.hpp: Made sure _syncer pointer is not disturbed
+ by assignments.
+
+2007-11-30 10:53 fmhess
+
+ * poet/monitor.hpp: Made poet::monitor provide scoped_try_lock and
+ scoped_timed_lock, it is now based off timed_monitor_ptr and used
+ boost::timed_mutex as its default mutex type. The mutex type
+ must now be a model of the TimedMutex concept from Boost Thread.
+
+2007-11-30 10:49 fmhess
+
+ * poet/monitor_ptr.hpp: Fixed compile warning.
+
+2007-11-30 09:57 fmhess
+
+ * poet/monitor.hpp: Added poet::monitor, which stores the wrapped
+ object by value and does deep copies, instead of acting like a
+ smart pointer (as monitor_ptr does). This implementation took
+ the quick and easy route of being based on monitor_ptr.
+
+2007-11-30 09:38 fmhess
+
+ * poet/monitor_ptr.hpp: Made constructors from raw pointers
+ template functions, to take advantage of cleverness of shared_ptr
+ constructors. Added reset(). Made
+ monitor_ptr_scoped_lock::wait_function private.
+
+2007-11-27 17:42 fmhess
+
+ * doc/boostbook/monitor_ptr_hpp.xml: Updated monitor_ptr docs to
+ reflect recent additions/changes.
+
+2007-11-27 13:43 fmhess
+
+ * poet/monitor_ptr.hpp: Made scoped locks in monitor_ptr
+ noncopyable. Added monitor_ptr::call_proxy which is a thin
+ wrapper around monitor_ptr::scoped_lock that makes it suitable
+ (that is, copyable) for return from the monitor_ptr member access
+ operator. Fixed a mis-named constructor for timed_monitor_ptr.
+
+2007-11-27 12:04 fmhess
+
+ * poet/: monitor_ptr.hpp, detail/monitor_synchronizer.hpp: Added
+ scoped lock types to monitor_ptr, and try_monitor_ptr and
+ timed_monitor_ptr. Scoped locks provide member access operator
+ and dereference operator. Replaced monitor_call_proxy with
+ scoped lock (plan make scoped locks noncopyable and use
+ shared_ptr<scoped_lock> instead). Had to replace weak_ptr to
+ scoped_lock in monitor_synchronizer to support different types of
+ scoped locks, since the current version of boost::condition
+ requires a lock object from boost.thread.
+
+2007-11-27 11:50 fmhess
+
+ * poet/acyclic_mutex.hpp: Made names of acyclic lock classes more
+ distinguished by adding "acyclic_" to the beginnings.
+
+2007-11-26 14:21 fmhess
+
+ * poet/acyclic_mutex.hpp: re-added some missing "typename"
+ keywords.
+
+2007-11-26 14:13 fmhess
+
+ * poet/acyclic_mutex.hpp: Actually, we do need to template acyclic
+ locks on underlying lock type.
+
+2007-11-26 11:29 fmhess
+
+ * poet/: monitor_base.hpp, monitor_ptr.hpp, mutex_grapher.hpp,
+ detail/monitor_base.ipp, detail/monitor_base_decl.hpp,
+ detail/mutex_grapher.ipp, detail/mutex_grapher_decl.hpp: Don't
+ need separate .hpp and _decl.hpp files.
+
+2007-11-26 10:31 fmhess
+
+ * poet/detail/: mutex_grapher.ipp, mutex_grapher_decl.hpp: Added
+ mutex_grapher::set_cycle_hander() and made default handler call
+ std::abort().
+
+2007-11-26 10:14 fmhess
+
+ * poet/acyclic_mutex.hpp: Fixed compile error.
+
+2007-11-23 09:43 fmhess
+
+ * poet/acyclic_mutex.hpp: acyclic lock types don't need Lock
+ template parameter.
+
+2007-11-21 14:40 fmhess
+
+ * poet/: acyclic_mutex.hpp, detail/acyclic_mutex_base.hpp,
+ detail/mutex_grapher_decl.hpp, detail/static_mutex.hpp,
+ detail/template_static.hpp: Replaced static_mutex with more
+ general template_static. Included a skeleton implementation of
+ acyclic_mutex_base when ACYCLIC_MUTEX_NDEBUG is defined.
+
+2007-11-21 11:47 fmhess
+
+ * poet/: acyclic_mutex.hpp, mutex_grapher.hpp,
+ detail/acyclic_mutex_base.hpp, detail/mutex_grapher.ipp,
+ detail/mutex_grapher_decl.hpp, detail/static_mutex.hpp: Initial
+ pass at supporting mutexes which automatically detect lock-order
+ violations.
+
+2007-11-21 11:01 fmhess
+
+ * poet/monitor_ptr.hpp: Made monitor_ptr constructor from raw
+ pointer explicit.
+
+2007-11-18 12:53 fmhess
+
+ * poet/: monitor_ptr.hpp, detail/monitor_synchronizer.hpp: Fixed
+ bug where synchronizer's _current_lock would be wrong after
+ returning from a wait().
+
+2007-11-18 12:20 fmhess
+
+ * poet/detail/monitor_synchronizer_base.hpp: Removed obsolete file.
+
+2007-11-15 11:39 fmhess
+
+ * README, doc/boostbook/libpoet_doc.xml: Specify programming
+ language at the beginning of the docs.
+
+2007-11-15 11:11 tag v2007_11-15
+
+2007-11-15 11:11 fmhess
+
+ * doc/boostbook/: monitor_base_hpp.xml, monitor_ptr_hpp.xml: Fixed
+ hyperlinks to monitor.pdf.
+
+2007-11-15 10:59 fmhess
+
+ * doc/boostbook/: monitor_base_hpp.xml, monitor_ptr_hpp.xml: Fixed
+ text on links to monitor_demo.cpp
+
+2007-11-15 10:52 fmhess
+
+ * README: Added a line about monitor objects to the README
+
+2007-11-15 10:44 fmhess
+
+ * examples/monitor_demo.cpp: Added demo code for monitor classes.
+
+2007-11-15 10:43 fmhess
+
+ * doc/boostbook/: active_function_hpp.xml, active_object_hpp.xml,
+ libpoet_doc.xml, monitor_base_hpp.xml, monitor_ptr_hpp.xml: Added
+ a little to the descriptions of active_function and scheduler
+ classes. Added links to example code in relevant class
+ descriptions.
+
+2007-11-15 09:14 fmhess
+
+ * doc/boostbook/: Makefile, libpoet_doc.xml, libpoet_reference.xml,
+ monitor_base_hpp.xml, monitor_ptr_hpp.xml: Added documentation
+ for monitor_base.
+
+2007-11-14 10:32 fmhess
+
+ * poet/: monitor_base.hpp, monitor_ptr.hpp,
+ detail/monitor_base.ipp, detail/monitor_base_decl.hpp,
+ detail/monitor_synchronizer.hpp,
+ detail/monitor_synchronizer_base.hpp: Added poet::monitor_ptr and
+ poet::monitor_base which support monitor objects.
+
+2007-10-23 16:23 fmhess
+
+ * doc/boostbook/: Makefile, libpoet_reference.xml,
+ monitor_ptr_hpp.xml: Added documentation for monitor_ptr.
+
+2007-10-23 16:22 fmhess
+
+ * doc/boostbook/future_hpp.xml: Added a missing <para> element.
+
+2007-10-23 16:21 fmhess
+
+ * poet/monitor_ptr.hpp: Added typedef for
+ monitor_ptr::element_type. Removed monitor_ptr::set_value() and
+ get_value() since they don't really behave the same as the
+ locking done for operator->().
+
+2007-10-23 10:49 fmhess
+
+ * poet/monitor_ptr.hpp: Added monitor_ptr class.
+
+2007-10-13 22:55 fmhess
+
+ * doc/boostbook/active_object_hpp.xml: connectUpdate is called
+ connect_update now. Also added missing <para> that was producing
+ invalid docbook.
+
+2007-10-12 09:24 fmhess
+
+ * poet/active_object.hpp: Added some missing 'inline's to prevent
+ multiple definition linker errors.
+
+2007-09-20 13:30 tag v2007_09_20
+
+2007-09-20 13:30 fmhess
+
+ * doc/boostbook/libpoet_doc.xml: Updated boostbook version, since
+ we are using the new <access> tags.
+
+2007-09-20 13:29 fmhess
+
+ * README: Updated location of html docs, and removed mention of
+ doxygen.
+
+2007-09-11 16:53 fmhess
+
+ * doc/boostbook/: exception_ptr_hpp.xml, future_hpp.xml: Added a
+ little exposition on the fact that future::get() can throw
+ exceptions that got dropped in the doxygen->boostbook transition.
+
+2007-09-11 15:33 fmhess
+
+ * doc/boostbook/: active_function_hpp.xml, active_object_hpp.xml,
+ exception_ptr_hpp.xml, exceptions_hpp.xml, future_hpp.xml,
+ libpoet_doc.xml: Some tweaks to make the xml conform more closely
+ to the boostbook.dtd (modified to add support for access
+ elements). Validated with xmllint.
+
+2007-09-11 09:13 fmhess
+
+ * poet/: active_object.hpp, exception_ptr.cpp, exception_ptr.hpp,
+ exceptions.hpp, future.hpp: Stripped out obsolete doxygen
+ comments.
+
+2007-09-11 09:03 fmhess
+
+ * doc/: Doxyfile, doxygen_bogus.h, doxygen_future_void.h,
+ doxygen_mainpage.h: Removed obsolete Doxygen files.
+
+2007-09-10 16:26 fmhess
+
+ * doc/boostbook/: active_object_hpp.xml, exceptions_hpp.xml: Added
+ <classname> elements to <inherit> elements.
+
+2007-09-10 15:58 fmhess
+
+ * doc/boostbook/: active_function_hpp.xml, active_object_hpp.xml,
+ exceptions_hpp.xml, future_hpp.xml: Some minor documentation
+ cleanups.
+
+2007-09-10 12:40 fmhess
+
+ * doc/boostbook/future_hpp.xml: Got rid of a couple "throws
+ unspecified" documentation lines.
+
+2007-09-10 11:53 fmhess
+
+ * doc/boostbook/: exceptions_hpp.xml, future_hpp.xml: Added more
+ use of the <access> element, and some other minor documentation
+ enhancements.
+
+2007-09-10 10:51 fmhess
+
+ * doc/boostbook/active_object_hpp.xml: Added use of my new <access>
+ boostbook element, and made a few other minor documentation
+ enhancements.
+
+2007-09-07 17:52 fmhess
+
+ * doc/boostbook/: active_function_hpp.xml, active_object_hpp.xml,
+ libpoet_doc.xml: More improvements to boostbook docs. Starting
+ to make use of new <access> element I've added to boostbook.
+
+2007-09-07 17:23 fmhess
+
+ * poet/active_object.hpp, poet/detail/active_function_template.hpp,
+ test/active_object_test.cpp: Renamed
+ method_request_base::_updateSignal to update_signal.
+
+2007-09-06 16:16 fmhess
+
+ * doc/boostbook/: Makefile, active_function_hpp.xml,
+ exception_ptr_hpp.xml, exceptions_hpp.xml, future_hpp.xml,
+ libpoet_doc.xml: boostbook version of documentation is shaping up
+ nicely now.
+
+2007-09-06 13:46 fmhess
+
+ * poet/future.hpp: Made promise destructor virtual.
+
+2007-09-05 17:38 fmhess
+
+ * doc/boostbook/: Makefile, active_function_hpp.xml,
+ active_object_hpp.xml, exception_ptr_hpp.xml, exceptions_hpp.xml,
+ future_hpp.xml, libpoet_doc.xml, libpoet_reference.xml: Some more
+ work improving boostbook-based docs.
+
+2007-09-05 17:36 fmhess
+
+ * poet/: active_object.hpp, detail/active_function_template.hpp:
+ method_request::_returnValue has to be protected after all. Also
+ renamed it to return_value.
+
+2007-09-05 16:30 fmhess
+
+ * poet/: active_object.hpp, detail/active_object.cpp: Renamed
+ getRequest() to get_request() for consistency.
+
+2007-09-05 16:19 fmhess
+
+ * poet/active_object.hpp: Made some bits of method_request private.
+
+2007-09-05 11:19 fmhess
+
+ * doc/boostbook/: Makefile, catalog.xml, libpoet_reference.xml:
+ First pass at porting documentation from docbook to boostbook.
+
+2007-04-03 14:26 tag v2007_04_03
+
+2007-04-03 14:26 fmhess
+
+ * doc/doxygen_future_void.h: New file for doxygen docs on
+ future<void> and promise<void> specializations.
+
+2007-04-03 14:25 fmhess
+
+ * doc/Doxyfile, doc/doxygen_bogus.h, doc/doxygen_mainpage.h,
+ poet/exception_ptr.hpp, poet/future.hpp: Documentation updates.
+
+2007-04-02 15:59 fmhess
+
+ * poet/detail/active_function_template.hpp: Moved
+ active_function_method_request back into poet::detail namespace,
+ as it isn't very useful by itself after all.
+
+2007-04-02 15:26 fmhess
+
+ * test/active_function_test.cpp: Gave myclass a data member to make
+ tracking slightly more meaningful.
+
+2007-04-02 15:22 fmhess
+
+ * test/active_function_test.cpp: Added test of passive slot
+ tracking.
+
+2007-04-02 13:39 fmhess
+
+ * examples/active_object_example.cpp, poet/active_function.hpp,
+ poet/detail/active_function_template.hpp: Moved
+ active_function_method_requestN classes into main poet namespace.
+ Added overload of active_function constructor that is convenient
+ if you want to specifiy the scheduler but no guard.
+
+2007-03-30 16:30 fmhess
+
+ * poet/future.hpp: Tweaked promise<void> copy constructor.
+
+2007-03-30 16:28 fmhess
+
+ * poet/future.hpp, test/Makefile, test/active_object_test.cpp,
+ test/future_void_test.cpp: Added support for conversion from
+ promise with arbitrary template type to promise<void>
+
+2007-03-30 15:43 fmhess
+
+ * test/not_default_constructible_test.cpp: New test.
+
+2007-03-30 11:15 fmhess
+
+ * poet/future.hpp: Replaced some equality tests using optional with
+ optional::operator! since the equality tests seemed to be testing
+ something I didn't intend.
+
+2007-03-30 10:50 fmhess
+
+ * test/: Makefile, future_void_test.cpp, timed_join_test.cpp: Added
+ new test.
+
+2007-03-30 10:45 fmhess
+
+ * poet/future.hpp: Make future<anything> convertible to
+ future<void>
+
+2007-03-30 10:45 fmhess
+
+ * examples/active_object_example.cpp: More exposition in comments.
+
+2007-03-30 10:09 fmhess
+
+ * doc/doxygen_mainpage.h, examples/active_object_example.cpp,
+ poet/future.hpp, test/Makefile, test/timed_join_test.cpp: Added
+ future::timed_join()
+
+2007-03-29 15:24 fmhess
+
+ * doc/doxygen_bogus.h: Added new example to doxygen documentation.
+
+2007-03-29 15:19 fmhess
+
+ * examples/active_object_example.cpp: Added new example program
+
+2007-03-29 10:42 fmhess
+
+ * examples/pipeline.cpp: Added a little more exposition.
+
+2007-03-29 10:33 fmhess
+
+ * examples/pipeline.cpp: Added explicit use of promise class to
+ pipline example program.
+
+2007-03-22 10:15 fmhess
+
+ * poet/detail/active_function_template.hpp: Added missing call to
+ base class's postconstruct in active_function_method_request.
+ Made active_function_method_request::ready return true if any of
+ its input futures have exceptions.
+
+2007-03-22 10:14 fmhess
+
+ * poet/active_object.hpp: Removed pointless temporary variable.
+
+2007-03-22 10:12 fmhess
+
+ * test/active_function_test.cpp: Added test of cancellation of an
+ active_function method request.
+
+2007-03-20 14:09 fmhess
+
+ * doc/doxygen_mainpage.h: Added a missing word, and tweaked a
+ sentence.
+
+2007-03-20 13:26 fmhess
+
+ * doc/doxygen_bogus.h: Use pipeline.cpp as example program.
+
+2007-03-20 13:25 fmhess
+
+ * doc/Doxyfile: Look in examples subdir for example programs.
+
+2007-03-20 13:25 fmhess
+
+ * doc/doxygen_mainpage.h: Use pipeline.cpp as example, instead of
+ test program.
+
+2007-03-20 13:24 fmhess
+
+ * examples/pipeline.cpp: tweaked comments.
+
+2007-03-20 12:12 fmhess
+
+ * examples/pipeline.cpp: Added example.
+
+2007-03-20 10:59 fmhess
+
+ * poet/exception_ptr.cpp: Moved some exception_ptr implementation
+ details out of global namespace.
+
+2007-03-20 10:53 fmhess
+
+ * test/: Makefile, undead_active_function_test.cpp: Added new test.
+
+2007-03-20 10:52 fmhess
+
+ * poet/detail/active_object.cpp: Initialize
+ scheduler_impl::_wakePending member variable.
+
+2007-03-20 10:29 fmhess
+
+ * test/: Makefile, promise_count_test.cpp: Added test of promise
+ reference counting.
+
+2007-03-20 10:29 fmhess
+
+ * test/exception_test.cpp: Added some more assertions to exception
+ test.
+
+2007-03-20 10:15 fmhess
+
+ * poet/exception_ptr.cpp, poet/exception_ptr.hpp,
+ poet/exceptions.hpp, poet/future.hpp,
+ poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, poet/detail/condition.hpp,
+ test/active_function_test.cpp, test/active_object_test.cpp,
+ test/exception_test.cpp, test/future_test.cpp: Added boost
+ licence to file comments.
+
+2007-03-20 10:04 fmhess
+
+ * poet/future.hpp, test/exception_test.cpp: Added explicit get()
+ function to get a future's value.
+
+2007-03-20 09:32 fmhess
+
+ * poet/future.hpp: Work around compiler bug in g++ 3.3.5
+
+2007-03-20 09:25 fmhess
+
+ * test/: Makefile, exception_test.cpp: Added test of exception
+ forwarding.
+
+2007-03-20 09:17 fmhess
+
+ * poet/detail/active_function_template.hpp: Fixed breakage of
+ non-void return values with active_function.
+
+2007-03-20 09:10 fmhess
+
+ * poet/: future.hpp, detail/active_function_template.hpp: Add
+ support for void return values.
+
+2007-03-19 16:13 fmhess
+
+ * poet/: exception_ptr.cpp, exception_ptr.hpp, exceptions.hpp,
+ future.hpp: Split exception classes into their own header file.
+ Added support for more types of exceptions to exception_ptr.
+
+2007-03-19 16:12 fmhess
+
+ * README, doc/doxygen_mainpage.h: Tweaked docs.
+
+2007-03-19 14:49 fmhess
+
+ * doc/doxygen_bogus.h, doc/doxygen_mainpage.h,
+ poet/active_object.hpp, poet/future.hpp: doxygen documentation
+ updates.
+
+2007-03-19 14:11 fmhess
+
+ * poet/future.hpp: Throw uncertain_future if an attempt is made to
+ dereference a future whose promise has already been destroyed
+ without fulfillment.
+
+2007-03-19 11:39 fmhess
+
+ * poet/: active_object.hpp, detail/active_object.cpp: Use a more
+ boost-like naming scheme for activation queue classes.
+
+2007-03-19 11:18 fmhess
+
+ * poet/active_object.hpp, poet/detail/active_object.cpp,
+ test/Makefile: Don't kill scheduler thread when scheduler object
+ is destroyed. Instead, allow scheduler to continue running until
+ its activation queue is empty.
+
+2007-03-19 10:04 fmhess
+
+ * poet/future.hpp, test/future_test.cpp: Removed future constructor
+ that takes a conversion function, as the same functionality is
+ already available through active_function.
+
+2007-03-16 17:15 fmhess
+
+ * doc/doxygen_bogus.h, poet/active_function.hpp,
+ poet/active_object.hpp, poet/exception_ptr.cpp,
+ poet/exception_ptr.hpp, poet/future.hpp,
+ poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, test/active_object_test.cpp,
+ test/future_test.cpp: doxygen documentation updates. Split off
+ promise class from future class. Tweaked some method names.
+ Added support for transporting exceptions from passive functions
+ in the scheduler thread to futures.
+
+2007-03-15 13:26 fmhess
+
+ * README: Added a little README
+
+2007-03-15 11:23 fmhess
+
+ * poet/: exception_ptr.cpp, exception_ptr.hpp: Imported unmodified
+ exception_ptr code from Peter Dimov's exception_ptr proposal.
+ Will modify to suit libpoet's needs better.
+
+2007-03-13 16:45 fmhess
+
+ * doc/doxygen_bogus.h: Added a documentation stub for boost::slot,
+ and some links to the thread_safe_signals documentation.
+
+2007-03-13 16:25 fmhess
+
+ * doc/doxygen_bogus.h, poet/active_function.hpp,
+ poet/detail/active_function_template.hpp: Use a boost::slot from
+ thread_safe_signals to handle tracking of object lifetimes.
+
+2007-03-13 16:23 fmhess
+
+ * poet/active_object.hpp: Declared a bunch of functions inline,
+ since active_object.cpp is #include'd now.
+
+2007-03-13 16:22 fmhess
+
+ * test/Makefile: Removed misplaced doc target.
+
+2007-03-09 20:58 fmhess
+
+ * doc/doxygen_mainpage.h: Added dependencies section.
+
+2007-03-09 20:52 fmhess
+
+ * doc/doxygen_mainpage.h: Added status and discussion sections to
+ main page.
+
+2007-03-09 20:45 fmhess
+
+ * doc/doxygen_mainpage.h: Filled out main page of doxygen docs
+
+2007-03-09 17:24 tag initial_import
+
+2007-03-09 17:24 fmhess
+
+ * LICENSE_1_0.txt, doc/Doxyfile, doc/doxygen_bogus.h,
+ doc/doxygen_mainpage.h, poet/active_function.hpp,
+ poet/active_object.hpp, poet/future.hpp,
+ poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, poet/detail/condition.hpp,
+ test/Makefile, test/active_function_test.cpp,
+ test/active_object_test.cpp, test/future_test.cpp: Initial import
+ of libpoet "Parallel Object Execution Threads" active object
+ framework.
+
+2007-03-09 17:24 fmhess
+
+ * LICENSE_1_0.txt, doc/Doxyfile, doc/doxygen_bogus.h,
+ doc/doxygen_mainpage.h, poet/active_function.hpp,
+ poet/active_object.hpp, poet/future.hpp,
+ poet/detail/active_function_template.hpp,
+ poet/detail/active_object.cpp, poet/detail/condition.hpp,
+ test/Makefile, test/active_function_test.cpp,
+ test/active_object_test.cpp, test/future_test.cpp: Initial
+ revision
+
Added: sandbox/libpoet/trunk/LICENSE_1_0.txt
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/LICENSE_1_0.txt 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,23 @@
+Boost Software License - Version 1.0 - August 17th, 2003
+
+Permission is hereby granted, free of charge, to any person or organization
+obtaining a copy of the software and accompanying documentation covered by
+this license (the "Software") to use, reproduce, display, distribute,
+execute, and transmit the Software, and to prepare derivative works of the
+Software, and to permit third-parties to whom the Software is furnished to
+do so, all subject to the following:
+
+The copyright notices in the Software and this entire statement, including
+the above license grant, this restriction and the following disclaimer,
+must be included in all copies of the Software, in whole or in part, and
+all derivative works of the Software, unless such copies or derivative
+works are solely in the form of machine-executable object code generated by
+a source language processor.
+
+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, TITLE AND NON-INFRINGEMENT. IN NO EVENT
+SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
+FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
Added: sandbox/libpoet/trunk/README
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/README 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,13 @@
+libpoet: Parallel Object Execution Threads
+
+libpoet is a C++ parallel programing library. It provides support for easily
+creating active objects, creating monitor objects, and automatically
+validating mutex locking order.
+
+The release tarballs should have html documentation in the doc/boostbook/html
+subdirectory.
+
+The libpoet documentation is also online:
+
+http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/index.html
+
Added: sandbox/libpoet/trunk/doc/boostbook/HTML.manifest
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/HTML.manifest 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1 @@
+poet.section.examples.html
Added: sandbox/libpoet/trunk/doc/boostbook/Makefile
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/Makefile 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,48 @@
+PROJECT_ROOT="../../.."
+BOOST_SRC_DIR=~/svn/boost_docs/
+BOOSTBOOK_TOOL_DIR=$(BOOST_SRC_DIR)/tools/boostbook
+
+XML_SRCS=\
+ active_function_hpp.xml \
+ active_object_hpp.xml \
+ acyclic_mutex_base_hpp.xml \
+ acyclic_mutex_hpp.xml \
+ exception_ptr_hpp.xml \
+ exceptions_hpp.xml \
+ future_hpp.xml \
+ future_barrier_hpp.xml \
+ future_select_hpp.xml \
+ libpoet_doc.xml \
+ libpoet_reference.xml \
+ monitor_base_hpp.xml \
+ monitor_ptr_hpp.xml \
+ monitor_hpp.xml \
+ monitor_locks_hpp.xml \
+ mutex_grapher_hpp.xml \
+ mutex_properties_hpp.xml
+
+.PHONY: all
+all: doc
+
+.PHONY: clean
+clean:
+ $(RM) -r html/*
+ $(RM) libpoet_doc.docbook
+
+.PHONY: doc
+doc: html
+
+.PHONY: html
+html: libpoet_doc.docbook
+ (export XML_CATALOG_FILES="./catalog.xml /etc/xml/catalog";\
+ xsltproc --xinclude --stringparam boost.root $(PROJECT_ROOT) \
+ --stringparam chapters.select.box.show false \
+ --stringparam google.search.box.show false \
+ --stringparam toc.max.depth 4 \
+ --stringparam toc.section.depth 3 \
+ -o html/ $(BOOSTBOOK_TOOL_DIR)/xsl/html.xsl $<)
+ cp ./demo_locking_order_graph.png html/
+
+libpoet_doc.docbook: $(XML_SRCS)
+ (export XML_CATALOG_FILES="./catalog.xml /etc/xml/catalog";\
+ xsltproc --xinclude --stringparam boost.root $(PROJECT_ROOT) -o $@ $(BOOSTBOOK_TOOL_DIR)/xsl/docbook.xsl libpoet_doc.xml)
Added: sandbox/libpoet/trunk/doc/boostbook/active_function_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/active_function_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,112 @@
+<header name="poet/active_function.hpp">
+ <namespace name="poet">
+ <class name="active_function">
+ <template><template-type-parameter name="Signature"/></template>
+ <purpose>Create an active object from an ordinary function or object. </purpose>
+ <description>
+ <para>An <code>active_function</code> can be created in one step from an ordinary function
+ or function object. By default, an <code>active_function</code> is a fully functional active object
+ with its own scheduler. Multiple <code>active_function</code>s may also share a scheduler and
+ be combined to form more complicated active objects.
+ </para>
+ <para>In the following, the active_function is taken to have a signature of: <programlisting>active_function<R (T1, T2, ..., TN)></programlisting></para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.pipeline.cpp">pipeline.cpp</link>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="poet.example.transform.cpp">pipeline.cpp</link>
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <link linkend="poet.example.active_object_example.cpp">active_object_example.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <typedef name="passive_result_type">
+ <type>boost::function_traits<Signature>::result_type</type>
+ </typedef>
+ <typedef name="result_type">
+ <type><classname>poet::future</classname><passive_result_type></type>
+ </typedef>
+ <typedef name="passive_slot_type">
+ <type><classname>boost::slot</classname><Signature></type>
+ <description><para>Slot type for the passive function the active_function is constructed from.</para></description>
+ </typedef>
+ <method-group name="public member functions">
+ <overloaded-method name="operator()">
+ <signature>
+ <type>result_type</type>
+ <parameter name="arg1"><paramtype><classname>future</classname><T1></paramtype></parameter>
+ <parameter name="arg2"><paramtype><classname>future</classname><T2></paramtype></parameter>
+ <parameter name=""><paramtype>...</paramtype></parameter>
+ <parameter name="argN"><paramtype><classname>future</classname><TN></paramtype></parameter>
+ </signature>
+ <signature cv="const">
+ <type>result_type</type>
+ <parameter name="arg1"><paramtype><classname>future</classname><T1></paramtype></parameter>
+ <parameter name="arg2"><paramtype><classname>future</classname><T2></paramtype></parameter>
+ <parameter name=""><paramtype>...</paramtype></parameter>
+ <parameter name="argN"><paramtype><classname>future</classname><TN></paramtype></parameter>
+ </signature>
+ <description>
+ <para>Invocation creates a method request and sends it to the active_function's scheduler. The method request may be cancelled by calling <methodname>future::cancel</methodname>() on the returned <classname>future</classname>.</para>
+ <para>Note the active_function takes futures as arguments, as well as returning a <classname>future</classname>. This allows future results to be passed from one active_function to another without waiting for the result to become ready. Since futures are constructible from their value types, the active_function can also take ordinary values not wrapped in futures as arguments. </para>
+ </description>
+ </overloaded-method>
+ <method name="expired" cv="const">
+ <type>bool</type>
+ <description><para>Calls the boost::slot::expired() query method on the slot this active_function was constructed from. </para></description>
+ </method>
+ </method-group>
+ <constructor>
+ <parameter name="passive_function">
+ <paramtype>const <classname>passive_slot_type</classname> &</paramtype>
+ <description><para>The underlying function this active_function object will call. The boost::slot class supports tracking of arbitrary boost::shared_ptr which are associated with the slot. For example, if the slot is constructed from a non-static member function, the lifetime of the member function's object can be tracked and the slot prevented from running after the object is destroyed. </para></description>
+ </parameter>
+ <parameter name="scheduler">
+ <paramtype>boost::shared_ptr<<classname>scheduler_base</classname>></paramtype>
+ <default>boost::shared_ptr<scheduler_base>()</default>
+ <description><para>Specify a scheduler object for the active_function to post its method requests to. By default, a new Scheduler object is created for the active_function. If the active_function is providing a method as part of an active object class, you may wish for all the class' methods to share the same scheduler. </para></description>
+ </parameter>
+ <description><para></para></description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>const active_function &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ The copy constructor creates a shallow copy of <code>other</code>.
+ Both copies share the same scheduler and passive function.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <description><para>The default constructor creates an empty <code>active_function</code> which cannot be
+ used until it is assigned a useable <code>active_function</code>.</para></description>
+ </constructor>
+ <destructor specifiers="virtual">
+ <description><para>Virtual destructor. </para></description>
+ </destructor>
+ <copy-assignment>
+ <parameter name="rhs">
+ <paramtype>const active_function &</paramtype>
+ </parameter>
+ <description>
+ <para>Assignment turns <code>*this</code> into a shallow copy of <code>rhs</code>. Both copies share the
+ same scheduler and passive function.
+ </para>
+ </description>
+ </copy-assignment>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/active_object_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/active_object_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,299 @@
+<header name="poet/active_object.hpp">
+ <namespace name="poet">
+ <class name="method_request_base">
+ <purpose>Base class for method requests.</purpose>
+ <description>
+ <para>
+ <code>method_request_base</code> is the base class for the asynchronous method requests which are
+ queued in activation queues derived from <classname>activation_queue_base</classname>, and
+ executed by schedulers derived from <classname>scheduler_base</classname>.
+ </para>
+ <para>
+ If you are building active objects using <classname>active_function</classname>s, it
+ should not be necessary to use this class directly, as the definition and creation of
+ method requests are handled internally by <classname>active_function</classname>.
+ </para>
+ </description>
+ <access name="public">
+ <method-group name="public member functions">
+ <method name="run" cv="" specifiers="virtual">
+ <type>void</type>
+ <description><para>run() is called by schedulers to execute the method request. It will not
+ be called by the scheduler until the future returned by <methodname>scheduling_guard</methodname>
+ becomes ready or gets an exception.</para></description>
+ </method>
+ <method name="scheduling_guard" cv="const" specifiers="virtual">
+ <type><classname>future</classname><void></type>
+ <description>
+ <para>This function should return a future which becomes ready (or gets an exception) when the
+ method request is ready to be run.</para>
+ </description>
+ </method>
+ </method-group>
+ <constructor/>
+ <destructor specifiers="virtual"/>
+ </access>
+ </class>
+ <class name="activation_queue_base">
+ <purpose>Base class for activation queues. </purpose>
+ <description>
+ <para>
+ An activation queue is responsible for thread-safely transporting method requests
+ from the threads making asynchronous function calls to a scheduler thread for execution.
+ libpoet provides two activation queues derived from activation_queue_base:
+ <classname>out_of_order_activation_queue</classname> and
+ <classname>in_order_activation_queue</classname>.
+ </para>
+ </description>
+ <access name="public">
+ <typedef name="size_type">
+ <type>unsigned long</type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="push_back" cv="" specifiers="virtual">
+ <type>void</type>
+ <parameter name="request"><paramtype>const boost::shared_ptr<<classname>method_request_base</classname>> &</paramtype></parameter>
+ <description><para>Called to adds a new method request to the activation queue.</para></description>
+ </method>
+ <method name="get_request" cv="" specifiers="virtual">
+ <type>boost::shared_ptr<<classname>method_request_base</classname>></type>
+ <description>
+ <para>
+ <code>get_request</code> blocks until the next method request is ready to run, then pops
+ the request off
+ the queue and returns it. The <code>get_request</code> call may be forced to
+ return early by a call to <methodname>wake</methodname>. <code>get_request</code>
+ is called by schedulers to obtain method requests for execution.
+ </para>
+ </description>
+ <returns>
+ <para>
+ A method request which is ready to be run. If <code>get_request</code> was
+ interrupted by a <methodname>wake</methodname> call
+ before any method requests became ready,
+ it should return an empty <code>shared_ptr</code>.
+ </para>
+ </returns>
+ </method>
+ <method name="wake">
+ <type>void</type>
+ <description>
+ <para>
+ A call to <code>wake</code> should cause any <methodname>get_request</methodname>
+ calls which are waiting for a ready method request
+ to wake up immediately and return an empty <code>shared_ptr</code>.
+ </para>
+ </description>
+ </method>
+ <method name="size" cv="const" specifiers="virtual">
+ <type>size_type</type>
+ <description><para></para></description>
+ <returns><para>the number of method requests waiting in the queue. </para></returns>
+ </method>
+ <method name="empty" cv="const" specifiers="virtual">
+ <type>bool</type><description><para></para></description>
+ <returns><para>true if size() is zero. </para></returns>
+ </method>
+ </method-group>
+ <destructor specifiers="virtual">
+ </destructor>
+ </access>
+ </class>
+ <class name="in_order_activation_queue">
+ <inherit access="public"><type><classname>poet::activation_queue_base</classname></type></inherit>
+ <purpose>An activation queue which always keeps method requests in FIFO order. </purpose>
+ <description>
+ <para>An <code>in_order_activation_queue</code> will never skip over method requests that aren't ready yet.
+ If you don't require the method requests to be executed in the exact order they were received,
+ use an <classname>out_of_order_activation_queue</classname> instead.
+ </para>
+ </description>
+ <access name="public">
+ <method-group name="public member functions">
+ <method name="push_back" cv="" specifiers="virtual">
+ <type>void</type>
+ <parameter name="request"><paramtype>const boost::shared_ptr<<classname>method_request_base</classname>> &</paramtype></parameter>
+ <description><para>Adds a new method request to the activation queue. </para></description>
+ </method>
+ <method name="get_request" cv="" specifiers="virtual">
+ <type>boost::shared_ptr<<classname>method_request_base</classname>></type>
+ <description>
+ <para>
+ Blocks until the oldest method request in the queue becomes ready, then pops the request
+ off the queue and returns it.
+ </para>
+ </description>
+ <returns>
+ <para>
+ The oldest method request in the queue, or an empty shared_ptr if interrupted by <methodname>wake</methodname>.
+ </para>
+ </returns>
+ </method>
+ <method name="wake">
+ <type>void</type>
+ <description>
+ <para>
+ A call to <code>wake</code> should cause any <methodname>get_request</methodname>
+ calls which are waiting for a ready method request
+ to wake up immediately and return an empty shared_ptr.
+ </para>
+ </description>
+ </method>
+ <method name="size" cv="const" specifiers="virtual">
+ <type>size_type</type>
+ <description><para></para></description>
+ <returns><para>the number of method requests waiting in the queue. </para></returns>
+ </method>
+ <method name="empty" cv="const" specifiers="virtual">
+ <type>bool</type>
+ <description><para></para></description>
+ <returns><para>true if size() is zero. </para></returns>
+ </method>
+ </method-group>
+ <destructor specifiers="virtual"/>
+ </access>
+ </class>
+ <class name="out_of_order_activation_queue">
+ <inherit access="public"><type><classname>poet::activation_queue_base</classname></type></inherit>
+ <purpose>An activation queue which can reorder method requests. </purpose>
+ <description>
+ <para>
+ An out_of_order_activation_queue can return any method request it contains
+ which is currently ready for execution. Thus, method requests which are not ready will never
+ stall the queue and prevent
+ another ready method request from running.
+ </para>
+ </description>
+ <access name="public">
+ <method-group name="public member functions">
+ <method name="push_back" cv="" specifiers="virtual">
+ <type>void</type>
+ <parameter name="request"><paramtype>const boost::shared_ptr<<classname>method_request_base</classname>> &</paramtype></parameter>
+ <description><para>Adds a new method request to the activation queue. </para></description>
+ </method>
+ <method name="get_request" cv="" specifiers="virtual">
+ <type>boost::shared_ptr<<classname>method_request_base</classname>></type>
+ <description>
+ <para>
+ Blocks until any method request in the queue becomes ready, then pops the ready
+ request off the queue and returns it.
+ </para>
+ </description>
+ <returns>
+ <para>A method request from the queue which is currently ready for execution, or
+ an empty <code>shared_ptr</code> if interrupted by <methodname>wake</methodname>.
+ </para>
+ </returns>
+ </method>
+ <method name="wake">
+ <type>void</type>
+ <description>
+ <para>
+ A call to <code>wake</code> should cause any <methodname>get_request</methodname>
+ calls which are waiting for a ready method request
+ to wake up immediately and return an empty shared_ptr.
+ </para>
+ </description>
+ </method>
+ <method name="size" cv="const" specifiers="virtual">
+ <type>size_type</type>
+ <description><para></para></description>
+ <returns><para>the number of method requests waiting in the queue. </para></returns>
+ </method>
+ <method name="empty" cv="const" specifiers="virtual">
+ <type>bool</type>
+ <description><para></para></description>
+ <returns><para>true if size() is zero. </para></returns>
+ </method>
+ </method-group>
+ <destructor specifiers="virtual"/>
+ </access>
+ </class>
+ <class name="scheduler_base">
+ <purpose>Base class for schedulers. </purpose>
+ <description><para>A scheduler creates its own thread and executes method requests which are passed to it through its activation queue. </para></description>
+ <access name="public">
+ <method-group name="public member functions">
+ <method name="post_method_request" cv="" specifiers="virtual">
+ <type>void</type>
+ <parameter name="request"><paramtype>const boost::shared_ptr<<classname>method_request_base</classname>> &</paramtype></parameter>
+ <description><para>Adds <code>request</code> to the scheduler's activation queue.</para></description>
+ </method>
+ <method name="kill" cv="" specifiers="virtual">
+ <type>void</type>
+ <description>
+ <para>
+ Tells scheduler thread to exit as soon as possible. The scheduler thread may still be running after this function returns.
+ </para>
+ </description>
+ </method>
+ <method name="join" cv="" specifiers="virtual">
+ <type>void</type>
+ <description><para>Blocks until the scheduler thread exits. </para></description>
+ </method>
+ </method-group>
+ <destructor specifiers="virtual">
+ <description><para>Virtual destructor. </para></description>
+ </destructor>
+ </access>
+ </class>
+ <class name="scheduler">
+ <inherit access="public"><type><classname>poet::scheduler_base</classname></type></inherit>
+ <purpose>Execute method requests in a separate thread. </purpose>
+ <description>
+ <para>
+ A <code>scheduler</code> object creates a new thread of execution which pulls method
+ requests from an activation queue and executes them.
+ </para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.active_object_example.cpp">active_object_example.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <method-group name="public member functions">
+ <method name="post_method_request" cv="" specifiers="virtual">
+ <type>void</type>
+ <parameter name="request"><paramtype>const boost::shared_ptr<<classname>method_request_base</classname>> &</paramtype></parameter>
+ <description><para>Adds <code>request</code> to the scheduler's activation queue. </para></description>
+ </method>
+ <method name="kill" cv="" specifiers="virtual">
+ <type>void</type>
+ <description>
+ <para>
+ Tells scheduler thread to exit as soon as possible. The scheduler thread may still be running after this function returns.
+ </para>
+ </description>
+ </method>
+ <method name="join" cv="" specifiers="virtual">
+ <type>void</type>
+ <description><para>Blocks until the scheduler thread exits.</para></description>
+ </method>
+ </method-group>
+ <constructor>
+ <parameter name="queue">
+ <paramtype>const boost::shared_ptr<<classname>activation_queue_base</classname>> &</paramtype>
+ <default>boost::shared_ptr<activation_queue_base>(new <classname>out_of_order_activation_queue</classname>)</default>
+ <description><para>Allows use of a customized activation queue. By default, an <classname>out_of_order_activation_queue</classname> is allocated for use. </para></description>
+ </parameter>
+ <description>
+ <para>The scheduler constructer will create a new thread of execution, where the scheduler will execute method requests.</para>
+ </description>
+ </constructor>
+ <destructor specifiers="virtual">
+ <description>
+ <para>
+ The scheduler thread will continue to run after the scheduler object is destroyed,
+ until all method requests in its activation queue have been dispatched (unless the
+ <methodname>kill</methodname> method has been called).
+ </para>
+ </description>
+ </destructor>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/acyclic_mutex_base_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/acyclic_mutex_base_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,35 @@
+<header name="poet/acyclic_mutex_base.hpp">
+ <namespace name="poet">
+ <class name="acyclic_mutex_base">
+ <purpose>The base class of the <classname>acyclic_mutex</classname> template class.
+ </purpose>
+ <description>
+ <para>
+ The <code>acyclic_mutex_base</code> class gives access to an <classname>acyclic_mutex</classname>'s
+ vertex descriptor in <classname>mutex_grapher</classname>'s locking order graph.
+ </para>
+ </description>
+ <access name="public">
+ <method-group name="public member functions">
+ <method name="vertex" cv="const">
+ <type><classname>boost::optional</classname><<classname>mutex_grapher</classname>::<classname alt="mutex_grapher::locking_order_graph">locking_order_graph</classname>::vertex_descriptor></type>
+ <description>
+ <para>Returns the mutex's vertex descriptor in the locking order graph.
+ If the mutex has never been locked, it will have no vertex descriptor and
+ an uninitialized <classname>boost::optional</classname> is returned.
+ Additionally, if mutex debugging has been disabled by defining
+ <code>NDEBUG</code> or <code>ACYCLIC_MUTEX_NDEBUG</code>, then
+ an uninitialized <classname>boost::optional</classname> will always be returned.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ <destructor specifiers="virtual">
+ <description>
+ <para>Virtual destructor.</para>
+ </description>
+ </destructor>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/acyclic_mutex_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/acyclic_mutex_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,192 @@
+<header name="poet/acyclic_mutex.hpp">
+ <namespace name="poet">
+ <class name="acyclic_mutex">
+ <template>
+ <template-type-parameter name="Mutex">
+ <default>boost::mutex</default>
+ </template-type-parameter>
+ <template-type-parameter name="Key">
+ <default>std::string</default>
+ </template-type-parameter>
+ <template-type-parameter name="KeyCompare">
+ <default>std::less<Key></default>
+ </template-type-parameter>
+ </template>
+ <inherit access="public">
+ <type><classname>acyclic_mutex_base</classname></type>
+ </inherit>
+ <purpose>A mutex wrapper which automatically detects potential deadlocks
+ due to an inconsistent mutex locking order (e.g. deadly embrace).
+ </purpose>
+ <description>
+ <para>
+ The <code>acyclic_mutex</code> class automatically tracks the
+ order in which all the program's <code>acyclic_mutex</code> objects
+ are locked, and detects any potential deadlocks. It does so by
+ building up a graph in the <classname>mutex_grapher</classname> singleton
+ of the mutex locking order, which is checked to insure the locking
+ order remains consistent as the program executes.
+ </para>
+ <para>
+ An <code>acyclic_mutex</code> will model the same mutex concepts (see Boost.Thread
+ version 1.35.0 or later)
+ modeled by its <code>Mutex</code> template type. Thus, you may use any appropriate
+ lock type from Boost.Thread to lock an <code>acyclic_mutex</code> (for example,
+ a <code>boost::unique_lock</code>).
+ </para>
+ <para>
+ The <code>Mutex</code> template type may be any of the mutex classes provided by
+ Boost.Thread (version 1.35.0 or later) or libpoet itself. It may also be
+ a foreign mutex classes, as long as it models one of the
+ mutex concepts defined in the Boost.Thread documentation, and you define
+ a specialization of <classname>mutex_properties</classname> for the
+ foreign mutex class. However, recursive <code>SharedLockable</code>
+ and recursive <code>UpgradeLockable</code>
+ mutexes are not currently supported, due to there being no known implementations.
+ </para>
+ <para>
+ The <code>KeyCompare</code> template parameter must define a strict weak ordering
+ for the <code>Key</code> type. Note, this is
+ only used to determine if two keys are equivalent or not, and is not taken
+ to imply any particular locking order requirement between mutexes with inequivalent
+ keys. <code>acyclic_mutex</code> objects with equivalent keys share the same
+ vertex in the locking order graph built by <classname>mutex_grapher</classname>.
+ </para>
+ <para>
+ For production code, the tracking of mutex locking order may be disabled program-wide
+ at compile time by defining either <code>NDEBUG</code> or <code>ACYCLIC_MUTEX_NDEBUG</code>.
+ </para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.acyclic_mutex_demo.cpp">acyclic_mutex_demo.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <classname>mutex_grapher</classname>: used by <code>acyclic_mutex</code> objects to
+ build up a locking order graph, and test the locking order for potential deadlocks.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <typedef name="mutex_type">
+ <type>Mutex</type>
+ </typedef>
+ <typedef name="key_type">
+ <type>Key</type>
+ </typedef>
+ <typedef name="key_compare">
+ <type>KeyCompare</type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="node_key" cv="const">
+ <type><classname>boost::optional</classname><Key></type>
+ <description>
+ <para>Returns the mutex's key (wrapped in a <classname>boost::optional</classname>).
+ If the mutex was default constructed, it will have no key and
+ an uninitialized <classname>boost::optional</classname> is returned.
+ Additionally, if mutex debugging has been disabled by defining
+ <code>NDEBUG</code> or <code>ACYCLIC_MUTEX_NDEBUG</code>, then
+ this function will always return an uninitialized <classname>boost::optional</classname>.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread Lockable concept support">
+ <method name="lock">
+ <type>void</type>
+ </method>
+ <method name="try_lock">
+ <type>bool</type>
+ </method>
+ <method name="unlock">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread TimedLockable concept support">
+ <method name="timed_lock">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread SharedLockable concept support">
+ <method name="lock_shared">
+ <type>void</type>
+ </method>
+ <method name="try_lock_shared">
+ <type>bool</type>
+ </method>
+ <method name="timed_lock_shared">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ <method name="unlock_shared">
+ <type>void</type>
+ </method>
+ <method name="unlock_and_lock_shared">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread UpgradeLockable concept support">
+ <method name="lock_upgrade">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade_and_lock">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade_and_lock_shared">
+ <type>void</type>
+ </method>
+ <method name="unlock_and_lock_upgrade">
+ <type>void</type>
+ </method>
+ </method-group>
+ <constructor>
+ <description>
+ <para>The default constructor creates a mutex with no key. This causes the mutex to be allocated
+ its own vertex in the locking order graph. Default construction requires the least effort
+ from the user, and minimizes the possibility of false positives, but also incurs the most overhead
+ in the locking order graph of the <classname>mutex_grapher</classname>.
+ If your program allocates many mutex objects, it may be worth coming up with a scheme for
+ assigning keys to your mutexes.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="key">
+ <paramtype>const Key &</paramtype>
+ </parameter>
+ <description>
+ <para>Creates a mutex with the specified key. All mutexes with equivalent
+ (according to the <code>KeyCompare</code> ordering) keys
+ will share the same vertex in the locking order graph. This limits the size
+ of the locking order graph, and so can reduce overhead if your program creates
+ many mutex objects. However, it does require additional effort from the
+ programmer to group the mutexes by key in a way which will
+ not produce false positives.
+ </para>
+ </description>
+ </constructor>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/catalog.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/catalog.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<!DOCTYPE catalog
+ PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
+ "http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
+<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
+ <rewriteURI uriStartString="http://www.boost.org/tools/boostbook/dtd/" rewritePrefix="file:///home/fhess/svn/boost_docs/tools/boostbook/dtd/"/>
+</catalog>
Added: sandbox/libpoet/trunk/doc/boostbook/demo_locking_order_graph.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/boostbook/exception_ptr_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/exception_ptr_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,61 @@
+<header name="poet/exception_ptr.hpp">
+ <namespace name="poet">
+ <typedef name="exception_ptr">
+ <type>boost::shared_ptr<detail::_exp_throwable></type>
+ <purpose>Transport an arbitrary exception.</purpose>
+ <description>
+ <para>libpoet uses exception_ptr to transport an exception thrown by
+ a passive function being executed inside a scheduler thread to
+ a future waiting on its result. It is
+ adapted from Peter Dimov's
+ <ulink url="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2179.html">N2179 proposal</ulink>.
+ </para>
+ </description>
+ </typedef>
+ <function name="current_exception">
+ <type>exception_ptr</type>
+ <purpose>Get an exception_ptr which holds the current exception.</purpose>
+ <description>
+ <para>
+ current_exception() can be used inside a catch block to get a copy
+ of the current exception. This is especially useful inside catch(...)
+ blocks where there is no explicit parameter corresponding to the exception.
+ </para>
+ <para>
+ Due to the limitations of exception handling in C++, current_exception()
+ does not work perfectly. Only exception types specifically known by
+ the implementation are captured correctly. Exceptions derived from the
+ known exceptions will be captured as the most derived base class which
+ is a known exception. Other exceptions will only be captured as
+ <classname>poet::unknown_exception</classname> objects. If current_exception() can only
+ determine that the exception is derived from std::exception, then
+ the exception will also be captured as a <classname>poet::unknown_exception</classname>,
+ although it will capture the correct std::exception::what() string.
+ </para>
+ <para>
+ The implementation knows all the exceptions in <stdexcept>, as
+ well as all the exception classes in libpoet and some of the
+ exceptions specified in thread_safe_signals and boost.
+ </para>
+ <para>
+ libpoet uses current_exception() to transport an exception thrown
+ by a passive function in a method request being run in a
+ scheduler's thread
+ back to a thread waiting on a future corresponding to the method
+ request's return value.
+ </para>
+ </description>
+ </function>
+ <function name="rethrow_exception">
+ <type>void</type>
+ <parameter name="p"><paramtype>exception_ptr</paramtype></parameter>
+ <purpose>Throws the exception held by the exception_ptr</purpose>
+ </function>
+ <function name="copy_exception">
+ <template><template-type-parameter name="E"/></template>
+ <type>exception_ptr</type>
+ <parameter name="e"><paramtype>E</paramtype></parameter>
+ <purpose>Creates an exception_ptr from an exception.</purpose>
+ </function>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/exceptions_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/exceptions_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,36 @@
+<header name="poet/exceptions.hpp">
+ <namespace name="poet">
+ <class name="cancelled_future">
+ <inherit access="public"><type><classname>std::runtime_error</classname></type></inherit>
+ <purpose>Exception thrown by a cancelled future. </purpose>
+ <description><para>This exception is thrown when an attempt to convert a future to its associated value fails due to future::cancel() being called on a future that references the same promise. </para></description>
+ <access name="public">
+ <constructor/>
+ <destructor specifiers="virtual"/>
+ </access>
+ </class>
+ <class name="uncertain_future">
+ <inherit access="public"><type><classname>std::runtime_error</classname></type></inherit>
+ <purpose>Exception thrown by an uncertain future.</purpose>
+ <description><para>This exception is thrown when an attempt is made to convert a future with no promise into its associated value. This can happen if the future was default-constructed, or its associated promise object has been destroyed without being fulfilled. </para></description>
+ <access name="public">
+ <constructor/>
+ <destructor specifiers="virtual"/>
+ </access>
+ </class>
+ <class name="unknown_exception">
+ <inherit access="public"><type><classname>std::runtime_error</classname></type></inherit>
+ <purpose>Exception used as a placeholder for unknown exceptions. </purpose>
+ <description><para>Exceptions unknown by the current_exception() code are replaced with this class. It is also used to replace exceptions whose exact type is unknown but which are derived from std::exception, in which case the what() string will be made to match the what() string of the original unknown exception. </para></description>
+ <access name="public">
+ <constructor>
+ <parameter name="description">
+ <paramtype>const std::string &</paramtype>
+ <default>"poet::unknown_exception"</default>
+ </parameter>
+ </constructor>
+ <destructor specifiers="virtual"/>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/future_barrier_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/future_barrier_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,263 @@
+<header name="poet/future_barrier.hpp">
+ <namespace name="poet">
+ <overloaded-function name="future_barrier">
+ <purpose>construct a future which becomes ready when a group of futures are all ready.</purpose>
+ <signature>
+ <template>
+ <template-type-parameter name="T1"/>
+ <template-type-parameter name="T2"/>
+ </template>
+ <type><classname>future</classname><void></type>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ <parameter name="f2">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="T1"/>
+ <template-type-parameter name="T2, ..."/>
+ <template-type-parameter name="TN"/>
+ </template>
+ <type><classname>future</classname><void></type>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ <parameter name="f2">
+ <paramtype>const <classname>future</classname><T2> &</paramtype>
+ </parameter>
+ <parameter name="">
+ <paramtype>...</paramtype>
+ </parameter>
+ <parameter name="fN">
+ <paramtype>const <classname>future</classname><TN> &</paramtype>
+ </parameter>
+ </signature>
+ <description>
+ <para>
+ The <code>future_barrier</code> functions construct a future which can be used to
+ wait on a group of futures until they are all ready (or one has an exception).
+ </para>
+ <para>
+ By default, overloads which accept 2 to 10 future arguments are provided.
+ The user may obtain more or fewer overloads by defining the macro
+ <code>POET_FUTURE_BARRIER_MAX_ARGS</code> prior to including poet/future_barrier.hpp.
+ </para>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <functionname>future_barrier_range</functionname>: Same as <code>future_barrier</code> except it takes iterators to a range of futures as its parameters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_combining_barrier</functionname>: A more flexible version of <code>future_barrier</code>
+ which allows the user to create an arbitrary value/exception for the returned future based on the
+ values/exception of the input futures.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_select</functionname>: construct a future which becomes ready when any of a group of futures is ready or has an exception.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <returns>
+ <para>
+ A future which becomes ready when all of the input futures either become
+ ready or one has an exception. If one of the input futures has an exception, the
+ returned future will receive the same exception.
+ </para>
+ </returns>
+ </overloaded-function>
+ <function name="future_barrier_range">
+ <template>
+ <template-type-parameter name="FutureInputIterator"/>
+ </template>
+ <type><classname>future</classname><void></type>
+ <parameter name="first">
+ <paramtype>FutureInputIterator</paramtype>
+ </parameter>
+ <parameter name="last">
+ <paramtype>FutureInputIterator</paramtype>
+ </parameter>
+ <description>
+ <para>Similar to <functionname>future_barrier</functionname> except this version takes input iterators
+ to a range of futures as its input parameters.
+ </para>
+ </description>
+ </function>
+ <overloaded-function name="future_combining_barrier">
+ <purpose>construct a future based on the values from a group of futures.</purpose>
+ <signature>
+ <template>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="Combiner"/>
+ <template-type-parameter name="ExceptionHandler"/>
+ <template-type-parameter name="T1"/>
+ </template>
+ <type><classname>future</classname><R></type>
+ <parameter name="combiner">
+ <paramtype>const Combiner &</paramtype>
+ </parameter>
+ <parameter name="exception_handler">
+ <paramtype>const ExceptionHandler &</paramtype>
+ </parameter>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="Combiner"/>
+ <template-type-parameter name="ExceptionHandler"/>
+ <template-type-parameter name="T1"/>
+ <template-type-parameter name="T2"/>
+ </template>
+ <type><classname>future</classname><R></type>
+ <parameter name="combiner">
+ <paramtype>const Combiner &</paramtype>
+ </parameter>
+ <parameter name="exception_handler">
+ <paramtype>const ExceptionHandler &</paramtype>
+ </parameter>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ <parameter name="f2">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="Combiner"/>
+ <template-type-parameter name="ExceptionHandler"/>
+ <template-type-parameter name="T1"/>
+ <template-type-parameter name="T2, ..."/>
+ <template-type-parameter name="TN"/>
+ </template>
+ <type><classname>future</classname><R></type>
+ <parameter name="combiner">
+ <paramtype>const Combiner &</paramtype>
+ </parameter>
+ <parameter name="exception_handler">
+ <paramtype>const ExceptionHandler &</paramtype>
+ </parameter>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T1> &</paramtype>
+ </parameter>
+ <parameter name="f2">
+ <paramtype>const <classname>future</classname><T2> &</paramtype>
+ </parameter>
+ <parameter name="">
+ <paramtype>...</paramtype>
+ </parameter>
+ <parameter name="fN">
+ <paramtype>const <classname>future</classname><TN> &</paramtype>
+ </parameter>
+ </signature>
+ <description>
+ <para>
+ The <code>future_combining_barrier</code> function constructs a future which can be used to
+ wait on a group of futures until they are all ready (or one has an exception). The user
+ must specify the <code>combiner</code> and <code>exception_handler</code> functors,
+ which are used to generate the value/exception for the returned future based
+ on the values/exception of the input futures.
+ </para>
+ <para>
+ The template type parameter <code>R</code> determines the return type of the
+ function, and must be manually specified when calling <code>future_combining_barrier</code>.
+ The rest of the template type parameters may be deduced from the types of
+ the input parameters.
+ </para>
+ <para>
+ If all the input futures sucessfully become ready, the returned future
+ will become ready by obtaining its value from the return value of <code>combiner(v1, v2, ..., vN)</code>
+ where the <code>vN</code> parameters are the values associated with the input futures.
+ If any of the input futures is a future<void> (and thus has no value),
+ the user's <code>combiner</code> functor will
+ receive a placeholder value of type <classname>poet::null_type</classname>.
+ </para>
+ <para>
+ If any of the input futures has an exception, the
+ returned future will receive an exception based on the return value of
+ <code>exception_handler(ex_ptr)</code> where the <code>ex_ptr</code> parameter
+ will be an <classname>exception_ptr</classname> holding the exception from the input
+ future. The return value of the user's <code>exception_handler</code> functor
+ should be of type <classname>exception_ptr</classname> and hold the
+ exception which the user desires to be transported to the returned future.
+ </para>
+ <para>
+ By default, overloads which accept 1 to 10 future arguments are provided.
+ The user may obtain more or fewer overloads by defining the macro
+ <code>POET_FUTURE_BARRIER_MAX_ARGS</code> prior to including poet/future_barrier.hpp.
+ </para>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <functionname>future_combining_barrier_range</functionname>: Same as <code>future_combining_barrier</code> except it takes iterators to a range of futures as its parameters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_barrier</functionname>: A simpler, more limited version of
+ <code>future_combining_barrier</code> which returns a future<void>.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_select</functionname>: construct a future which becomes ready when any of a group of futures is ready or has an exception.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <returns>
+ <para>
+ A future which becomes ready when all of the input futures either become
+ ready or one has an exception.
+ </para>
+ </returns>
+ </overloaded-function>
+ <function name="future_combining_barrier_range">
+ <template>
+ <template-type-parameter name="R"/>
+ <template-type-parameter name="Combiner"/>
+ <template-type-parameter name="ExceptionHandler"/>
+ <template-type-parameter name="FutureInputIterator"/>
+ </template>
+ <type><classname>future</classname><R></type>
+ <parameter name="combiner">
+ <paramtype>const Combiner &</paramtype>
+ </parameter>
+ <parameter name="exception_handler">
+ <paramtype>const ExceptionHandler &</paramtype>
+ </parameter>
+ <parameter name="first">
+ <paramtype>FutureInputIterator</paramtype>
+ </parameter>
+ <parameter name="last">
+ <paramtype>FutureInputIterator</paramtype>
+ </parameter>
+ <description>
+ <para>Similar to <functionname>future_combining_barrier</functionname> except this version takes input iterators
+ to a range of futures as its input parameters.
+ </para>
+ </description>
+ </function>
+ <struct name="null_type">
+ <description>
+ <para><code>poet::null_type</code> is a default-constructible, copy-constructible, and assignable type
+ which is sometimes passed as an argument to combiners given to the <functionname>future_combining_barrier</functionname>
+ function. It is used as a placeholder for the non-existant value associated with a future<void>.
+ </para>
+ </description>
+ </struct>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/future_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/future_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,411 @@
+<header name="poet/future.hpp">
+ <namespace name="poet">
+ <class name="future">
+ <template><template-type-parameter name="T"/></template>
+ <purpose>A placeholder for a future value. </purpose>
+ <description>
+ <para>Futures are placeholders for values which may not exist yet. They may be used to conveniently
+ support asyncronous function calls with built-in thread safety.
+ Since a future can be returned before any result is actually ready, an asyncronous call can return a future immediately
+ without blocking the calling thread. The calling thread can then poll the future to determine when a result is ready, or
+ block on the future waiting for a result.
+ </para>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <functionname>future_barrier</functionname>: construct a future which becomes ready when all of a group of futures are ready or have an exception.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_select</functionname>: construct a future which becomes ready when any of a group of futures is ready or has an exception.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <typedef name="value_type">
+ <type>T</type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="ready" cv="const"><type>bool</type>
+ <description><para></para></description>
+ <returns><para>true if the future's value is initialized. </para></returns>
+ </method>
+ <method name="get" cv="const">
+ <type>const T &</type>
+ <description><para>get() is used to obtain an initialized value from a future. If the future is not ready, then get() will block until the future's promise is fulfilled or broken. The future's value may also be obtained without an explicit call to get(), through the conversion operator.</para></description>
+ <returns><para>the future's value. </para></returns>
+ <throws>
+ <para>
+ <classname>cancelled_future</classname> if the conversion fails due to
+ cancellation. If the future's promise is broken, get() will throw whatever exception
+ was specified by the <methodname>promise::renege</methodname>() call (subject
+ to the limitations of <classname>poet::exception_ptr</classname>).
+ </para>
+ </throws>
+ </method>
+ <method name="conversion-operator" cv="const">
+ <type>const T &</type>
+ <description><para>The conversion operator provides implicit conversions to values. It has the same effects as the explicit get() function. </para></description>
+ </method>
+ <method name="join" cv="const">
+ <type>void</type>
+ <description><para><code>join</code> blocks until either <methodname>ready</methodname> or
+ <methodname>has_exception</methodname> becomes true. Unlike the
+ <methodname>get</methodname> method, <code>join</code> will not throw if <methodname>has_exception</methodname>
+ is <code>true</code>.</para></description>
+ </method>
+ <method name="timed_join" cv="const">
+ <type>bool</type>
+ <parameter name="absolute_time"><paramtype>const boost::system_time &</paramtype></parameter>
+ <description><para><code>timed_join</code> blocks until <computeroutput>absolute_time</computeroutput> is reached,
+ or either <methodname>ready</methodname> or <methodname>has_exception</methodname> becomes true.</para></description>
+ <returns><para><code>true</code> if either <methodname>ready</methodname> or <methodname>has_exception</methodname>
+ return <code>true</code>.</para></returns>
+ </method>
+ <method name="has_exception" cv="const">
+ <type>bool</type>
+ <description><para></para></description>
+ <returns><para><code>true</code> if this future's promise has been broken. Attempting to get the future's value will throw an exception that may give more information on why the promise was broken. </para></returns>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other"><paramtype>future &</paramtype></parameter>
+ <description><para>Swaps <code>*this</code> with <code>other</code>.</para></description>
+ </method>
+ </method-group>
+ <constructor>
+ <parameter name="promise"><paramtype>const <classname>promise</classname><T> &</paramtype></parameter>
+ <description><para>Creates a new future from a promise. When the promise referenced by promise is fulfilled, the future will become ready. </para></description>
+ </constructor>
+ <constructor><template><template-type-parameter name="OtherType"/></template>
+ <parameter name="promise"><paramtype>const <classname>promise</classname><OtherType> &</paramtype></parameter>
+ <description><para>Creates a new future from a promise with a template type <code>OtherType</code> that is implicitly convertible to the future's value_type. When the <classname>promise</classname> referenced by <code>promise</code> is fulfilled, the future will become ready. </para></description>
+ </constructor>
+ <constructor><parameter name="value"><paramtype>const T &</paramtype></parameter>
+ <description><para>Creates a new future with an initialized value, and provides implicit conversion from a value to the corresponding future. </para></description>
+ </constructor>
+ <constructor>
+ <template><template-type-parameter name="OtherType"/></template>
+ <parameter name="value"><paramtype>const OtherType &</paramtype></parameter>
+ <description>
+ <para>
+ Creates a new future with an initialized value, and provides implicit conversion from a value to the corresponding future.
+ The <code>OtherType</code> type must be implicitly convertible to <code>T</code>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other"><paramtype>const <classname>future</classname> &</paramtype></parameter>
+ <description><para>Creates a future from another future with an identical template type.
+ The two futures will both reference the same <classname>promise</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <template><template-type-parameter name="OtherType"/></template>
+ <parameter name="other"><paramtype>const <classname>future</classname><OtherType> &</paramtype></parameter>
+ <description><para>Creates a future from another future with a compatible template type. <code>*this</code> will
+ indirectly reference the <classname>promise</classname> or <code>other</code>, obtaining its value
+ by implicit conversion of <code>other</code>'s value once it is ready. </para></description>
+ </constructor>
+ <constructor>
+ <description><para>Creates an uncertain future with no promise. An attempt to get an uncertain future's value will throw an <classname>uncertain_future</classname> exception. An uncertain future may gain promise by assigning it another future with promise. </para></description>
+ </constructor>
+ <destructor specifiers="virtual">
+ <description><para></para></description>
+ </destructor>
+ <copy-assignment>
+ <parameter name="rhs"><paramtype>const <classname>future</classname> &</paramtype></parameter>
+ <description><para>Assignment from a future with an identical template type results in
+ two futures which share the same promise.</para></description>
+ </copy-assignment>
+ <copy-assignment>
+ <template><template-type-parameter name="OtherType"/></template>
+ <parameter name="rhs"><paramtype>const <classname>future</classname><OtherType> &</paramtype></parameter>
+ <description><para>Assignment from a future<U> is supported if <code>U</code> is implicitly convertible to
+ <code>T</code>. The assignment happens immediately, and does not block waiting for <code>other</code> to become ready. </para></description>
+ </copy-assignment>
+ </access>
+ <free-function-group name="free functions">
+ <function name="swap">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type>void</type>
+ <parameter name="a"><paramtype>future<T> &</paramtype></parameter>
+ <parameter name="b"><paramtype>future<T> &</paramtype></parameter>
+ <description><para>Swaps futures <code>a</code> and <code>b</code>.</para></description>
+ </function>
+ </free-function-group>
+ </class>
+ <class-specialization name="future">
+ <template></template>
+ <specialization>
+ <template-arg>void</template-arg>
+ </specialization>
+ <purpose>A void specialization of the future template class. </purpose>
+ <description><para>future<void> is for futures with no value. For example, it may be used to wait on the completion of an asynchronous function which has no return value. In addition, a future<void> can assigned or constructed from a future<T> where T is any type. This allows a future<void> to be used by code which is only interested in whether the future is ready or has an exception, and is not interested in the future's specific value or template type. </para></description>
+ <access name="public">
+ <typedef name="value_type">
+ <type>void</type>
+ </typedef>
+ <constructor>
+ <parameter name="promise_in"><paramtype>const <classname>promise</classname><void> &</paramtype></parameter>
+ <description><para>Same as the corresponding constructor for an unspecialized <classname>future</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="OtherType"/>
+ </template>
+ <parameter name="promise"><paramtype>const <classname>promise</classname><OtherType> &</paramtype></parameter>
+ <description><para>A future<void> can be constructed from any type of <classname>promise</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <parameter name="other"><paramtype>const <classname>future</classname> &</paramtype></parameter>
+ <description><para>Same as the corresponding constructor for an unspecialized <classname>future</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <template><template-type-parameter name="OtherType"/></template>
+ <parameter name="other"><paramtype>const <classname>future</classname><OtherType> &</paramtype></parameter>
+ <description><para>A future<void> can be constructed from any type of <classname>future</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <description><para>Same as the corresponding function for an unspecialized <classname>future</classname>.</para></description>
+ </constructor>
+ <destructor specifiers="virtual">
+ <description><para> </para></description>
+ </destructor>
+ <method-group name="public member functions">
+ <method name="get" cv="const">
+ <type>void</type>
+ <description><para>A future<void> has no value, but get() can still be used to block until the future's promise is fulfilled or reneged.</para></description>
+ </method>
+ <method name="conversion-operator" cv="const">
+ <type>void</type>
+ <description><para>The conversion operator has the same effects as the explicit get() function. </para></description>
+ </method>
+ <method name="join" cv="const">
+ <type>void</type>
+ <description><para>Same as the corresponding function for an unspecialized <classname>future</classname>.</para></description>
+ </method>
+ <method name="timed_join" cv="const">
+ <type>bool</type>
+ <parameter name="absolute_time"><paramtype>const boost::system_time &</paramtype></parameter>
+ <description><para>Same as the corresponding function for an unspecialized <classname>future</classname>.</para></description>
+ </method>
+ <method name="ready" cv="const">
+ <type>bool</type>
+ <description><para>Same as the corresponding function for an unspecialized <classname>future</classname>.</para></description>
+ </method>
+ <method name="has_exception" cv="const">
+ <type>bool</type>
+ <description><para>Same as the corresponding function for an unspecialized <classname>future</classname>.</para></description>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other"><paramtype>future &</paramtype></parameter>
+ <description><para>Swaps <code>*this</code> with <code>other</code>.</para></description>
+ </method>
+ </method-group>
+ <copy-assignment>
+ <parameter name="rhs"><paramtype>const <classname>future</classname> &</paramtype></parameter>
+ <description><para>Same as the corresponding function for an unspecialized <classname>future</classname>.</para></description>
+ </copy-assignment>
+ <copy-assignment>
+ <template>
+ <template-type-parameter name="OtherType"/>
+ </template>
+ <parameter name="other"><paramtype>const <classname>future</classname><OtherType> &</paramtype>
+ </parameter>
+ <description><para>A future<void> can be assigned any type of future.</para></description>
+ </copy-assignment>
+ </access>
+ </class-specialization>
+ <class name="promise">
+ <template><template-type-parameter name="T"/></template>
+ <purpose>A handle to a promise. </purpose>
+ <description>
+ <para>Promises are used to construct <classname>future</classname>s and set their values when they become available. You can also renege on a promise, which transports an exception instead of a value to any futures waiting on the promise.</para>
+ <para>Promise objects are handles with shallow copy semantics. Promises are reference-counted, which means a promise will automatically be reneged with an <classname>uncertain_future</classname> exception if its reference count drops to zero without the promise being fulfilled.</para>
+ <para>The idea of making a seperate promise class from the future class was suggested by Chirtopher Kohlhoff. The idea of reference counting the promise class was due to Braddock Gaskill. </para>
+ </description>
+ <access name="public">
+ <typedef name="value_type">
+ <type>T</type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="fulfill" cv="">
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <type>void</type>
+ <parameter name="value"><paramtype>const U &</paramtype></parameter>
+ <description>
+ <para>Fulfill the promise by giving it a value. All futures which reference this promise will become ready.
+ The type <code>U</code> must be implicitly convertible to the promise's template type <code>T</code>.
+ </para>
+ </description>
+ </method>
+ <method name="fulfill" cv="">
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <type>void</type>
+ <parameter name="future_value"><paramtype>const <classname>future</classname><U> &</paramtype></parameter>
+ <description>
+ <para>Chain the promise to another promise by giving it a future.
+ All futures which reference this promise will receive the value from future_value when it becomes ready.
+ If the promise referenced by future_value is broken, this promise will also be broken.
+ The type <code>U</code> must be implicitly convertible to the promise's template type <code>T</code>.
+ </para>
+ </description>
+ </method>
+ <method name="has_future" cv="const">
+ <type>bool</type>
+ <description>
+ <para>
+ The <code>has_future</code> query allows a promise-fulfilling thread to query if there are any futures left
+ which refer to this promise. This enables a promise-fulfilling thread to exit early if noone
+ is interested in its result.
+ </para>
+ </description>
+ <returns>
+ <para><code>true</code> if there are any <classname>future</classname> objects in existance which
+ will obtain their value/exception from this promise.
+ </para>
+ </returns>
+ </method>
+ <method name="reset">
+ <type>void</type>
+ <description>
+ <para>
+ Resets the promise by swapping it with a default-constructed promise.
+ </para>
+ </description>
+ <postconditions>
+ <para>
+ <code>has_future()==false</code>
+ </para>
+ </postconditions>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other"><paramtype>promise &</paramtype></parameter>
+ <description>
+ <para>
+ Swaps <code>*this</code> with <code>other</code>.
+ </para>
+ </description>
+ </method>
+ <overloaded-method name="renege">
+ <signature>
+ <template><template-type-parameter name="E"/></template>
+ <type>void</type>
+ <parameter name="exception"><paramtype>const E &</paramtype></parameter>
+ </signature>
+ <signature>
+ <type>void</type>
+ <parameter name="exp"><paramtype>const poet::exception_ptr &</paramtype></parameter>
+ </signature>
+ <description><para>Breaks the promise. Any futures which reference the promise will throw a copy of exception when they attempt to get their value. </para></description>
+ </overloaded-method>
+ </method-group>
+ <constructor/>
+ <constructor>
+ <parameter name="other"><paramtype>const promise &</paramtype></parameter>
+ <description><para>Copy construction creates a shallow copy of <code>other</code>.</para></description>
+ </constructor>
+ <copy-assignment>
+ <parameter name="rhs"><paramtype>const <classname>promise</classname> &</paramtype></parameter>
+ <description><para>Assignment makes <code>*this</code> a shallow copy of <code>rhs</code>.</para></description>
+ </copy-assignment>
+ </access>
+ <free-function-group name="free functions">
+ <function name="swap">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type>void</type>
+ <parameter name="a"><paramtype>promise<T> &</paramtype></parameter>
+ <parameter name="b"><paramtype>promise<T> &</paramtype></parameter>
+ <description><para>Swaps promises <code>a</code> and <code>b</code>.</para></description>
+ </function>
+ </free-function-group>
+ </class>
+ <class-specialization name="promise">
+ <template></template>
+ <specialization>
+ <template-arg>void</template-arg>
+ </specialization>
+ <purpose>A void specialization of the promise template class. </purpose>
+ <description><para>promise<void> may be used to create future<void> objects which have no value. In addition, a promise<void> can be constructed from a promise<T> where T is any type. This allows a promise<void> to be used by code which only needs to be able to renege on a promise and not fulfill it. </para></description>
+ <access name="public">
+ <typedef name="value_type">
+ <type>void</type>
+ </typedef>
+ <constructor>
+ <description><para>Same as the corresponding constructor for an unspecialized <classname>promise</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <parameter name="other"><paramtype>const <classname>promise</classname> &</paramtype></parameter>
+ <description><para>Same as the corresponding constructor for an unspecialized <classname>promise</classname>.</para></description>
+ </constructor>
+ <constructor>
+ <template><template-type-parameter name="OtherType"/></template>
+ <parameter name="other">
+ <paramtype>const <classname>promise</classname><OtherType> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ A promise<void> may be constructed from a promise with any template type, although it cannot
+ fulfill such a promise. It can renege on the promise, however.
+ </para>
+ </description>
+ </constructor>
+ <copy-assignment>
+ <parameter name="rhs"><paramtype>const <classname>promise</classname> &</paramtype></parameter>
+ <description><para>Assignment makes <code>*this</code> a shallow copy of <code>rhs</code>.</para></description>
+ </copy-assignment>
+ <destructor specifiers="virtual"/>
+ <method-group name="public member functions">
+ <method name="fulfill" cv="">
+ <type>void</type>
+ <parameter name="future_value"><paramtype>const <classname>future</classname><void> &</paramtype></parameter>
+ <description><para>Same as the corresponding function for an unspecialized <classname>promise</classname>.</para></description>
+ </method>
+ <method name="fulfill" cv="">
+ <type>void</type>
+ <description><para>Will make any future<void> objects referencing this promise become ready.</para></description>
+ <throws><simpara><classname>std::invalid_argument</classname> </simpara></throws>
+ </method>
+ <method name="has_future" cv="const">
+ <type>bool</type>
+ <description><para>Same as the corresponding function for an unspecialized <classname>promise</classname>.</para></description>
+ </method>
+ <method name="reset">
+ <type>void</type>
+ <description><para>Same as the corresponding function for an unspecialized <classname>promise</classname>.</para></description>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other"><paramtype>promise &</paramtype></parameter>
+ <description><para>Same as the corresponding function for an unspecialized <classname>promise</classname>.</para></description>
+ </method>
+ <overloaded-method name="renege">
+ <signature>
+ <template><template-type-parameter name="E"/></template>
+ <type>void</type>
+ <parameter name="exception"><paramtype>const E &</paramtype></parameter>
+ </signature>
+ <signature>
+ <type>void</type>
+ <parameter name="exp"><paramtype>const poet::exception_ptr &</paramtype></parameter>
+ </signature>
+ <description><para>Same as the corresponding function for an unspecialized <classname>promise</classname>.</para></description>
+ </overloaded-method>
+ </method-group>
+ </access>
+ </class-specialization>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/future_select_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/future_select_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,297 @@
+<header name="poet/future_select.hpp">
+ <namespace name="poet">
+ <overloaded-function name="future_select">
+ <purpose>construct a future from the first complete future of a group.</purpose>
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type><classname>future</classname><T></type>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T> &</paramtype>
+ </parameter>
+ <parameter name="f2">
+ <paramtype>const <classname>future</classname><T> &</paramtype>
+ </parameter>
+ </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type><classname>future</classname><T></type>
+ <parameter name="f1">
+ <paramtype>const <classname>future</classname><T> &</paramtype>
+ </parameter>
+ <parameter name="f2">
+ <paramtype>const <classname>future</classname><T> &</paramtype>
+ </parameter>
+ <parameter name="">
+ <paramtype>...</paramtype>
+ </parameter>
+ <parameter name="fN">
+ <paramtype>const <classname>future</classname><T> &</paramtype>
+ </parameter>
+ </signature>
+ <description>
+ <para>
+ The <code>future_select</code> function constructs a future which can be used to
+ wait on a group of futures until any one is ready (or has an exception).
+ </para>
+ <para>
+ By default, overloads which accept 2 to 10 future arguments are provided.
+ The user may obtain more or fewer overloads by defining the macro
+ <code>POET_FUTURE_SELECT_MAX_ARGS</code> prior to including poet/future_select.hpp.
+ </para>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <functionname>future_select_range</functionname>: Same as <code>future_select</code> except
+ it takes iterators to a range of futures as its parameters.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <classname>future_selector</classname>: Efficiently perform repeated waits
+ on a group of futures, waiting for the next future to become ready.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_barrier</functionname>: construct a future which becomes ready when all of a
+ group of futures are ready or one has an exception.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <returns>
+ <para>
+ A future which becomes ready when any one of the input futures either become
+ ready or has an exception. The returned future will receive the value/exception
+ of the input future which became ready (or has an exception).
+ </para>
+ </returns>
+ </overloaded-function>
+ <function name="future_select_range">
+ <template>
+ <template-type-parameter name="InputFutureIterator"/>
+ </template>
+ <type><classname>future</classname><std::iterator_traits<InputFutureIterator>::value_type></type>
+ <parameter name="first">
+ <paramtype>InputFutureIterator</paramtype>
+ </parameter>
+ <parameter name="last">
+ <paramtype>InputFutureIterator</paramtype>
+ </parameter>
+ <description>
+ <para>Similar to <functionname>future_select</functionname> except this version takes input iterators
+ to a range of futures as its input parameters.
+ </para>
+ </description>
+ </function>
+ <class name="future_selector">
+ <purpose>efficient repeated waits on a group of futures</purpose>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <description>
+ <para><code>future_selector</code> allows you to obtain futures which will become ready when
+ any future in a group of futures becomes ready. It is more efficient than maintaining
+ a separate container of futures and repeatedly passing them to
+ <functionname>future_select_range</functionname>.
+ </para>
+ <para>Most of the methods of <code>future_selector</code> are thread-safe. The exceptions
+ to this rule are:
+ <methodname>reset</methodname>, <methodname>swap</methodname>, and the assignment operator.
+ </para>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <functionname>future_select</functionname>: construct a future which becomes ready when
+ any of a group of futures is ready or has an exception.
+ </para>
+ </listitem>
+ <listitem>
+ <para>
+ <functionname>future_barrier</functionname>: construct a future which becomes ready when all of a
+ group of futures are ready or one has an exception.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <typedef name="value_type">
+ <type>future<T></type>
+ </typedef>
+ <typedef name="size_type">
+ <type>std::size_t</type>
+ </typedef>
+ <typedef name="difference_type">
+ <type>std::ptrdiff_t</type>
+ </typedef>
+ <constructor>
+ <description>
+ <para>
+ Constructs a future_selector containing no futures. Futures may be added to the
+ <code>future_selector</code> with the <methodname>push</methodname> method.
+ </para>
+ </description>
+ <postconditions>
+ <para>
+ <code>size() == 0</code>
+ </para>
+ </postconditions>
+ </constructor>
+ <constructor>
+ <parameter name="other"><paramtype>const future_selector &</paramtype></parameter>
+ <description>
+ <para><code>*this</code> will receive
+ a copy of all the futures in <code>other</code>. Copy construction has deep copy semantics,
+ so calling methods such as
+ <methodname>push</methodname> or <methodname>pop_selected</methodname>
+ on a future_selector copy will not effect the original, and vice-versa.
+ </para>
+ </description>
+ <postconditions>
+ <para>
+ <code>this->size() == other.size()</code>
+ </para>
+ </postconditions>
+ </constructor>
+ <destructor>
+ <description>
+ <para>
+ Any futures contained in the
+ <code>future_selector</code> at its time of destruction will be kept alive
+ as long as needed and to fulfill any remaining "selected futures" previously obtained
+ from calls to the <methodname>selected</methodname> method,
+ even after the <code>future_selector</code> itself has been destroyed.
+ However, any "selected futures" which no longer have any possibility
+ of being fulfilled, due to an insufficient number of futures contained
+ in the <code>future_selector</code> at the time of its destruction
+ (that is, <methodname>size</methodname> returns a negative value),
+ will be automatically reneged with an <code>uncertain_future</code>
+ exception.
+ </para>
+ </description>
+ </destructor>
+ <copy-assignment>
+ <parameter name="rhs"><paramtype>const future_selector &</paramtype></parameter>
+ <description>
+ <para>Copy-constructs a temporary <code>future_selector</code> from <code>rhs</code>,
+ then swaps it with <code>*this</code>.
+ </para>
+ </description>
+ <postconditions>
+ <para>
+ <code>this->size() == rhs.size()</code>
+ </para>
+ </postconditions>
+ </copy-assignment>
+ <method-group name="public member functions">
+ <method name="selected" cv="const">
+ <type>future<T></type>
+ <description>
+ <para>
+ Returns a future which will receive the value or exception of the next future
+ in the <code>future_selector</code> to complete. The "selected future" returned
+ will be fulfilled only after any selected futures obtained prior to the last
+ <methodname>pop_selected</methodname> call are fulfilled.
+ </para>
+ </description>
+ </method>
+ <method name="pop_selected">
+ <type>void</type>
+ <description>
+ <para>
+ Removes a future from the <code>future_selector</code>, so subsequent calls
+ to <methodname>selected</methodname>
+ will return a different "selected future". The selected futures will
+ be fulfilled in the order they were popped out of the <code>future_selector</code>.
+ </para>
+ <para>
+ This method may be called before the future returned
+ by <methodname>selected</methodname> is actually complete.
+ It may even be called more times than the number of
+ futures which have been pushed into the <code>future_selector</code> with the <methodname>push</methodname>
+ method. This results in <methodname>size</methodname> returning a negative value,
+ until more futures are pushed into the <code>future_selector</code>.
+ </para>
+ </description>
+ </method>
+ <overloaded-method name="push">
+ <signature>
+ <type>void</type>
+ <parameter name="f"><paramtype>const future<T> &</paramtype></parameter>
+ </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="Converter"/>
+ <template-type-parameter name="U"/>
+ </template>
+ <type>void</type>
+ <parameter name="converter"><paramtype>const Converter &</paramtype></parameter>
+ <parameter name="exception_handler"><paramtype>const ExceptionHandler &</paramtype></parameter>
+ <parameter name="f"><paramtype>const future<U> &</paramtype></parameter>
+ </signature>
+ <description>
+ <para>
+ Adds a future to the <code>future_selector</code>. When the added future becomes ready or gets an exception,
+ it will be used to fulfill or renege the oldest "selected future" which has not yet completed.
+ </para>
+ <para>
+ The 3 argument overload of this function is provided for convenience, and is equivalent to
+ <code>push(poet::<functionname>future_combining_barrier</functionname><T>(converter, exception_handler, f))</code>.
+ </para>
+ </description>
+ </overloaded-method>
+ <method name="size" cv="const">
+ <type>difference_type</type>
+ <returns>
+ <para>The number of times <methodname>push</methodname> has been called, minus the number of times
+ <methodname>pop_selected</methodname> has been called, since the <code>future_selector</code>
+ was default-constructed or reset. This value may be negative.
+ </para>
+ </returns>
+ </method>
+ <method name="reset">
+ <type>void</type>
+ <description>
+ <para>
+ Default-constructs a temporary <code>future_selector</code> and swaps it with <code>*this</code>.
+ </para>
+ </description>
+ <postconditions>
+ <para>
+ <code>size() == 0</code>
+ </para>
+ </postconditions>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other"><paramtype>future_selector &</paramtype></parameter>
+ <description>
+ <para>
+ Swaps <code>*this</code> with <code>other</code>.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ </access>
+ <free-function-group name="free functions">
+ <function name="swap">
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <type>void</type>
+ <parameter name="a"><paramtype><classname>future_selector</classname><T> &</paramtype></parameter>
+ <parameter name="b"><paramtype><classname>future_selector</classname><T> &</paramtype></parameter>
+ <description>
+ <para>Swaps <classname>future_selector</classname>s a and b.</para>
+ </description>
+ </function>
+ </free-function-group>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/libpoet_doc.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/libpoet_doc.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,182 @@
+<?xml version="1.0" encoding="utf-8" standalone="no"?>
+<!DOCTYPE library PUBLIC "-//Boost//DTD BoostBook XML V1.1//EN"
+ "http://www.boost.org/tools/boostbook/dtd/boostbook.dtd">
+
+<library dirname="mydir" name="libpoet" id="libpoet">
+ <libraryinfo>
+ <author>
+ <firstname>Frank</firstname>
+ <othername>Mori</othername>
+ <surname>Hess</surname>
+ <email>fmhess_at_[hidden]</email>
+ </author>
+ <copyright>
+ <year>2006</year>
+ <year>2007</year>
+ <year>2008</year>
+ <holder>Frank Mori Hess</holder>
+ </copyright>
+ <librarypurpose>This is the purpose of my library.</librarypurpose>
+ <librarycategory name="category:concurrent-programming"/>
+ </libraryinfo>
+ <title>libpoet</title>
+ <section id="poet.section.main">
+ <title>Parallel Object Execution Threads</title>
+ <using-namespace name="poet"/>
+ <section id="poet.section.introduction">
+ <title>Introduction</title>
+ <para>
+ libpoet is a C++ parallel programing library. It provides support for easily creating active objects,
+ creating monitor objects, and automatically validating mutex locking order.
+ </para>
+ <para>
+ Active objects provide concurrency and thread-safety, since each active object
+ executes in its own thread. Futures are employed to communicate with active objects
+ in a thread-safe manner. To learn
+ more about the active object concept, see the paper
+ <ulink url="http://www.cs.wustl.edu/~schmidt/PDF/Act-Obj.pdf">"Active Object, An Object Behavioral Pattern for Concurrent Programming."</ulink>
+ by R. Greg Lavender and Douglas C. Schmidt.
+ Some of the more important active object classes in libpoet
+ are <classname>poet::active_function</classname>, <classname>poet::future</classname>,
+ and <classname>poet::scheduler</classname>.
+ </para>
+ <para>
+ Monitor objects provide thread-safety via automatically locked access to an object.
+ See the paper
+ <ulink url="http://www.cs.wustl.edu/~schmidt/PDF/monitor.pdf">"Monitor Object, An Object Behavioral Pattern for Concurrent Programming"</ulink>
+ by Douglas C. Schmidt for more information about monitor objects.
+ The <classname>poet::monitor_ptr</classname>, <classname>poet::monitor</classname>,
+ and <classname>poet::monitor_base</classname> classes in libpoet provide support for monitor
+ objects.
+ </para>
+ <para>
+ Finally, the <classname>poet::acyclic_mutex</classname> class provides
+ a wrapper for mutex classes which adds automatic validation of a program's
+ mutex locking order. Following a consistent locking order ensures your program
+ will not deadlock due to problems such as "deadly embrace" or the "dining philosophers"
+ problem.
+ </para>
+ <para>
+ A version of this documentation corresponding to the most recent release should
+ be available online at
+ <ulink url="http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/index.html">http://www.comedi.org/projects/libpoet/boostbook/doc/boostbook/html/index.html>
+ </para>
+ </section>
+ <section id="poet.section.status">
+ <title>Status</title>
+ <para>
+ The library's API is still undergoing some development, and may be refined as feedback
+ and experience clairifies areas which could be improved. It is anticipated that some
+ interfaces will change to keep in sync with API changes in the Boost libraries,
+ and to keep in
+ sync with relevant changes and additions to the C++ standard.
+ </para>
+ </section>
+ <section id="poet.section.dependencies">
+ <title>Dependencies</title>
+ <para>
+ libpoet depends on the <ulink url="http://www.boost.org">Boost C++ libraries</ulink>
+ version 1.39 or later, and requires linking to the Boost.Thread library (libboost_thread).
+ </para>
+ </section>
+ <section id="poet.section.download">
+ <title>Download</title>
+ <para>
+ The most recent release is available from the
+ <ulink url="http://www.boost-consulting.com/vault/index.php?&direction=0&order=&directory=Concurrent%20Programming/Active%20Objects">
+ Boost Vault</ulink>
+ (get the latest "libpoet-xxxx-xx-xx.tgz" file).
+ </para>
+ <para>
+ The current source code is also availabe via anonymous cvs:
+ <programlisting>cvs -d:pserver:anonymous_at_[hidden]:/cvs/comedi login
+cvs -d:pserver:anonymous_at_[hidden]:/cvs/comedi co libpoet</programlisting>
+ When prompted for a password, hit enter.
+ </para>
+ <para>
+ You can also
+ <ulink url="http://www.comedi.org/cgi-bin/viewcvs.cgi/libpoet/">browse the cvs online</ulink>.
+ </para>
+ <para>
+ The code (and this documentation) is licensed under the <ulink url="http://www.boost.org/LICENSE_1_0.txt">Boost Software License, Version 1.0</ulink>.
+ </para>
+ </section>
+ <section id="poet.section.installation">
+ <title>Installation</title>
+ <para>
+ libpoet is a header-only library. It may be used by simply unpacking the files and adding the location of
+ the top-level directory (which contains the "poet/" subdirectory) to your compiler's include path.
+ Alternatively, you may move the "poet/" subdirectory
+ into an existing include directory which is already in your include path.
+ </para>
+ </section>
+ <section id="poet.section.discussion">
+ <title>Discussion</title>
+ <para>
+ libpoet has a <ulink url="http://groups.google.com/group/libpoet">mailing list</ulink> hosted on Google Groups,
+ which may be used to discuss issues related to the library.
+ </para>
+ </section>
+ </section>
+ <xi:include href="libpoet_reference.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <section id="poet.section.examples">
+ <title>Example Programs</title>
+ <section id="poet.example.active_objects">
+ <title>Active Objects</title>
+ <section id="poet.example.active_object_example.cpp">
+ <title>active_object_example.cpp</title>
+ <para>
+ Download <ulink url="../../../examples/active_object_example.cpp">active_object_example.cpp</ulink>.
+ </para>
+ <programlisting><xi:include href="../../examples/active_object_example.cpp"
+ xmlns:xi="http://www.w3.org/2001/XInclude" parse="text"/></programlisting>
+ </section>
+ <section id="poet.example.pipeline.cpp">
+ <title>pipeline.cpp</title>
+ <para>
+ Download <ulink url="../../../examples/pipeline.cpp">pipeline.cpp</ulink>.
+ </para>
+ <programlisting><xi:include href="../../examples/pipeline.cpp"
+ xmlns:xi="http://www.w3.org/2001/XInclude" parse="text"/></programlisting>
+ </section>
+ <section id="poet.example.transform.cpp">
+ <title>transform.cpp</title>
+ <para>
+ Download <ulink url="../../../examples/transform.cpp">transform.cpp</ulink>.
+ </para>
+ <programlisting><xi:include href="../../examples/transform.cpp"
+ xmlns:xi="http://www.w3.org/2001/XInclude" parse="text"/></programlisting>
+ </section>
+ </section>
+ <section id="poet.example.monitor_objects">
+ <title>Monitor Objects</title>
+ <section id="poet.example.monitor_demo.cpp">
+ <title>monitor_demo.cpp</title>
+ <para>
+ Download <ulink url="../../../examples/monitor_demo.cpp">monitor_demo.cpp</ulink>.
+ </para>
+ <programlisting><xi:include href="../../examples/monitor_demo.cpp"
+ xmlns:xi="http://www.w3.org/2001/XInclude" parse="text"/></programlisting>
+ </section>
+ </section>
+ <section id="poet.example.mutex_debugging">
+ <title>Mutex Debugging</title>
+ <section id="poet.example.acyclic_mutex_demo.cpp">
+ <title>acyclic_mutex_demo.cpp</title>
+ <para>The acyclic_mutex_demo example program writes the following graph to
+ stdout (after processing
+ into PNG format with the "dot" program from the graphviz package):
+ </para>
+ <para>
+ <imagedata fileref="demo_locking_order_graph.png"/>
+ </para>
+ <para>
+ Download <ulink url="../../../examples/acyclic_mutex_demo.cpp">acyclic_mutex_demo.cpp</ulink>.
+ </para>
+ <programlisting><xi:include href="../../examples/acyclic_mutex_demo.cpp"
+ xmlns:xi="http://www.w3.org/2001/XInclude" parse="text"/></programlisting>
+ </section>
+ </section>
+ </section>
+</library>
Added: sandbox/libpoet/trunk/doc/boostbook/libpoet_reference.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/libpoet_reference.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,44 @@
+<library-reference id="libpoet_reference">
+ <section id="libpoet_reference.section.active_objects">
+ <title>Active Objects</title>
+ <xi:include href="active_object_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="active_function_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="exception_ptr_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="exceptions_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="future_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="future_barrier_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="future_select_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </section>
+ <section id="libpoet_reference.section.monitor_objects">
+ <title>Monitor Objects</title>
+ <xi:include href="monitor_base_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="monitor_ptr_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="monitor_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="monitor_locks_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </section>
+ <section id="libpoet_reference.section.mutex_debugging">
+ <title>Mutex Debugging</title>
+ <xi:include href="acyclic_mutex_base_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="acyclic_mutex_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ <xi:include href="mutex_grapher_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </section>
+ <section id="libpoet_reference.section.misc">
+ <title>Miscellaneous</title>
+ <xi:include href="mutex_properties_hpp.xml"
+ xmlns:xi="http://www.w3.org/2001/XInclude"/>
+ </section>
+</library-reference>
Added: sandbox/libpoet/trunk/doc/boostbook/monitor_base_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/monitor_base_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,73 @@
+<header name="poet/monitor_base.hpp">
+ <namespace name="poet">
+ <class name="monitor_base">
+ <purpose>A base class for monitor objects.</purpose>
+ <description>
+ <para>
+ Deriving from <code>monitor_base</code> allows a class (whose objects are managed by
+ a <classname>monitor_ptr</classname> or contained in a <classname>monitor</classname>)
+ to wait on conditions inside member functions, releasing the monitor's mutex until
+ the condition is satisfied. See <ulink url="http://www.cs.wustl.edu/~schmidt/PDF/monitor.pdf">"Monitor Object:
+ An Object Behavioral Pattern for Concurrent Programming"</ulink> by Douglas C. Schmidt
+ for more information on monitor objects.
+ </para>
+ <para>
+ Support for a <code>timed_wait()</code> could be added in the future.
+ </para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.monitor_demo.cpp">monitor_demo.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="protected">
+ <method-group name="protected member functions">
+ <overloaded-method name="wait">
+ <signature cv="const">
+ <type>void</type>
+ </signature>
+ <signature cv="const">
+ <template><template-type-parameter name="Pred"/></template>
+ <type>void</type>
+ <parameter name="pred"><paramtype>Pred</paramtype></parameter>
+ </signature>
+ <description>
+ <para>Blocks until the object is woken up by another thread via
+ <methodname>monitor_base::notify_all</methodname>() or <methodname>monitor_base::notify_one</methodname>().
+ The mutex in the object's associated <classname>monitor_ptr</classname> is unlocked
+ before the thread goes to sleep,
+ and then automatically reaquired when the thread wakes up again.
+ </para>
+ <para>
+ If the <code>pred</code> parameter is supplied, the call will return
+ when <code>pred()</code> returns <code>true</code>. <code>pred()</code>
+ will be checked when <code>wait()</code> is first entered, and whenever the
+ thread is woken by a notification. The mutex will be
+ locked when <code>pred()</code> is called.
+ </para>
+ </description>
+ </overloaded-method>
+ <method name="notify_all" cv="const">
+ <type>void</type>
+ <description>
+ <para>Wakes all threads which are currently blocking in <methodname>monitor_base::wait</methodname>() calls
+ on this object. If no threads are waiting, it has no effect.
+ </para>
+ </description>
+ </method>
+ <method name="notify_one" cv="const">
+ <type>void</type>
+ <description>
+ <para>Wakes a single thread which is currently blocking in a <methodname>monitor_base::wait</methodname>() call
+ on this object. If no threads are waiting, it has no effect.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/monitor_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/monitor_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,348 @@
+<header name="poet/monitor.hpp">
+ <namespace name="poet">
+ <class name="monitor">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Mutex">
+ <default>boost::mutex</default>
+ </template-type-parameter>
+ </template>
+ <purpose>A wrapper which provides automatically locked access to an object.</purpose>
+ <description>
+ <para>
+ <code>monitor</code> allows for the easy creation of monitor objects.
+ A <code>monitor</code> provides automatically locked access to its contained object's members
+ when they are accessed through the overloaded <methodname>operator-></methodname>,
+ or alternatively through one of the lock classes from
+ <link linkend="header.poet.monitor_locks.hpp">poet/monitor_locks.hpp</link>.
+ It is similar to a <classname>monitor_ptr</classname>, except it behaves like a value
+ instead of a smart pointer when copied.
+ Copies of a <code>monitor</code> object are deep copies with independent values, and
+ do not share the same mutex/condition.
+ </para>
+ <para>
+ Although any object may be wrapped in a <code>monitor</code>,
+ special support is provided
+ for classes derived from <classname>monitor_base</classname>. This allows classes derived from
+ <classname>monitor_base</classname> to wait on conditions inside member function calls,
+ releasing the <code>monitor</code>'s mutex until the condition is satisfied.
+ </para>
+ <para>
+ The <code>Mutex</code> template type parameter must model the <code>Lockable</code>
+ concept from the Boost.Thread library. The <code>monitor</code> itself models the
+ <code>Lockable</code> concept, and will also model any of the
+ <code>TimedLockable</code>, <code>SharedLockable</code>, or <code>UpgradeLockable</code>
+ concepts if the underlying <code>Mutex</code> template type supports them.
+ </para>
+ <para>
+ The interfaces defined by the Boost.Thread mutex concepts should generally
+ not be used directly by the user. They are intended to be used by
+ scoped lock classes such as <classname>monitor_unique_lock</classname>,
+ which provide a safer means to perform locking.
+ See the "Mutex Concepts" documentation in the Boost.Thread library
+ for more information about the Lockable, etc. concepts.
+ </para>
+ <para>
+ It is possible to obtain <classname>monitor_ptr</classname>s from a <code>monitor</code> which shares
+ ownership/mutex/condition and points at
+ the value wrapped in a <code>monitor</code> object, via the <methodname>get_monitor_ptr</methodname>
+ method. The value wrapped in a <code>monitor</code> object will not be destructed until
+ the last such <code>monitor_ptr</code> is destroyed, along with the <code>monitor</code>
+ object containing it, and any locks from
+ <link linkend="header.poet.monitor_locks.hpp">poet/monitor_locks.hpp</link>
+ which reference it.
+ </para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.monitor_demo.cpp">monitor_demo.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <classname>monitor_ptr</classname>: a pointer-like alternative to the <code>monitor</code> class.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <typedef name="element_type">
+ <type>T</type>
+ </typedef>
+ <typedef name="mutex_type">
+ <type>Mutex</type>
+ </typedef>
+ <method-group name="public member functions">
+ <overloaded-method name="get_monitor_ptr">
+ <signature>
+ <type>const <classname>monitor_ptr</classname><T, Mutex> &</type>
+ </signature>
+ <signature cv="const">
+ <type><classname>monitor_ptr</classname><const T, Mutex></type>
+ </signature>
+ <description>
+ <para>
+ The <code>get_monitor_ptr</code> method can be used to obtain a <classname>monitor_ptr</classname> which shares
+ ownership/mutex/condition with <code>*this</code>.
+ </para>
+ </description>
+ </overloaded-method>
+ <overloaded-method name="operator->">
+ <signature>
+ <type><classname>monitor_unique_lock</classname><monitor></type>
+ </signature>
+ <signature cv="const">
+ <type><classname>monitor_unique_lock</classname><const monitor></type>
+ </signature>
+ <description>
+ <para>Returns a temporary <classname>monitor_unique_lock</classname> which
+ locks the <code>monitor</code>'s mutex.
+ The <code>operator->()</code> of the returned <classname>monitor_unique_lock</classname>
+ object will be
+ automatically called in turn (overloading <code>operator->()</code> is special in that way), which will
+ utimately result in a call of <code>operator->()</code> on a pointer to the
+ <code>monitor</code>'s contained object.
+ The mutex is automatically unlocked after the member access completes by the
+ <classname>monitor_unique_lock</classname>
+ destructor.
+ </para>
+ <para>
+ If more flexibility is desired, the lock types from
+ <link linkend="header.poet.monitor_locks.hpp">poet/monitor_locks.hpp</link>
+ provide alternatives to <code>monitor::operator-></code>.
+ </para>
+ </description>
+ </overloaded-method>
+ <method name="swap">
+ <template>
+ <template-type-parameter name="M"/>
+ </template>
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>monitor<T, M> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Swaps the wrapped values of <code>*this</code> and <code>other</code>.
+ Only the wrapped values of the two monitors are swapped, not their mutexes
+ or condition variables.
+ </para>
+ <para>
+ The mutexes of both monitors are locked before
+ their values are swapped. The mutexes are locked by trying each of the
+ two possible locking orders until both mutexes are successfully locked.
+ This avoids any possibility of deadlock due to locking order violation,
+ but may produce false positives when using debugging tools such as
+ <classname>acyclic_mutex</classname>.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread Lockable concept support">
+ <method name="lock" cv="const">
+ <type>void</type>
+ </method>
+ <method name="try_lock" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="unlock" cv="const">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread TimedLockable concept support">
+ <method name="timed_lock" cv="const">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t" cv="const">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread SharedLockable concept support">
+ <method name="lock_shared" cv="const">
+ <type>void</type>
+ </method>
+ <method name="try_lock_shared" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="timed_lock_shared" cv="const">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t" cv="const">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ <method name="unlock_shared" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_and_lock_shared" cv="const">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread UpgradeLockable concept support">
+ <method name="lock_upgrade" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade_and_lock" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade_and_lock_shared" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_and_lock_upgrade" cv="const">
+ <type>void</type>
+ </method>
+ </method-group>
+ <copy-assignment>
+ <template>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="M"/>
+ </template>
+ <type>monitor<T, Mutex> &</type>
+ <parameter name="rhs">
+ <paramtype>const monitor<U, M> &</paramtype>
+ </parameter>
+ <requires>
+ <para>The template type <code>U</code> of <code>rhs</code>
+ must be implicitly convertible into the template type
+ <code>T</code> of <code>*this</code>.
+ </para>
+ </requires>
+ <description>
+ <para>Copies the contained value of type <code>U</code> from <code>rhs</code>
+ into <code>*this</code>.
+ </para>
+ <para>
+ The mutexes of both <code>*this</code> and <code>rhs</code> are locked before
+ the assignment is performed. The mutexes are locked by trying each of the
+ two possible locking orders until both mutexes are successfully locked.
+ This avoids any possibility of deadlock due to locking order violation,
+ but may produce false positives when using debugging tools such as
+ <classname>acyclic_mutex</classname>.
+ </para>
+ <para>
+ Copies of a <code>monitor</code> object are deep copies, which do not share
+ the same mutex or condition.
+ </para>
+ </description>
+ </copy-assignment>
+ <copy-assignment>
+ <parameter name="rhs">
+ <paramtype>const monitor &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Same as the templated assignment operator. This overload is provided to
+ prevent a default assignment operator from being generated.
+ </para>
+ </description>
+ </copy-assignment>
+ <constructor>
+ <description>
+ <para>Creates a <code>monitor</code> with a default-constructed value.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="value">
+ <paramtype>const T &</paramtype>
+ </parameter>
+ <description>
+ <para>Creates a <code>monitor</code> which contains a value copy-constructed from
+ the constructor's argument.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>const <classname>monitor</classname> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ The copy constructor creates a <code>monitor</code> whose contained value is
+ copy-constructed from the
+ value contained in the <code>other</code> parameter. <code>other</code> is
+ locked while its value is copied out.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="M"/>
+ </template>
+ <parameter name="other">
+ <paramtype>const <classname>monitor</classname><U, M> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Creates a <code>monitor</code> whose contained value is copy-constructed from the
+ value contained in the <code>other</code> parameter. The type <code>U</code> must
+ be implicitly convertible to type <code>T</code>. <code>other</code> is
+ locked while its value is copied out.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="U1"/>
+ <template-type-parameter name="U2"/>
+ <template-type-parameter name="..."/>
+ <template-type-parameter name="UN"/>
+ </template>
+ <parameter name="arg1"><paramtype>U1</paramtype></parameter>
+ <parameter name="arg2"><paramtype>U2</paramtype></parameter>
+ <parameter><paramtype>...</paramtype></parameter>
+ <parameter name="argN"><paramtype>UN</paramtype></parameter>
+ <description>
+ <para>
+ Creates a <code>monitor</code> by forwarding the constructor's arguments
+ to the constructor for the contained value. If you need to pass
+ a reference to the contained value's constructor, you should wrap it
+ in a <classname>boost::reference_wrapper</classname> to prevent it
+ from being automatically converted to a value.
+ </para>
+ <para>
+ If you wish to change the maximum number of arguments this family of constructors can take
+ from its default value of 10, you may define the macro <code>POET_MONITOR_MAX_CONSTRUCTOR_ARGS</code>
+ to your desired value prior to including monitor.hpp.
+ </para>
+ </description>
+ </constructor>
+ <destructor specifiers="virtual"/>
+ </access>
+ <free-function-group name="free function: swap">
+ <function name="swap">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Mutex"/>
+ </template>
+ <parameter name="monitor0"><paramtype>monitor<T, Mutex> &</paramtype></parameter>
+ <parameter name="monitor1"><paramtype>monitor<T, Mutex> &</paramtype></parameter>
+ <type>void</type>
+ <description>
+ <para>
+ Swaps the values of <code>monitor0</code> and <code>monitor1</code>. This
+ function is provided to
+ enhance efficiency with generic algorithms.
+ </para>
+ </description>
+ <effects>
+ <para><code>monitor0.swap(monitor1);</code></para>
+ </effects>
+ </function>
+ </free-function-group>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/monitor_locks_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/monitor_locks_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,930 @@
+<header name="poet/monitor_locks.hpp">
+ <namespace name="poet">
+ <class name="monitor_unique_lock">
+ <template>
+ <template-type-parameter name="MonitorType"/>
+ </template>
+ <purpose>unique_lock with monitor object access</purpose>
+ <description>
+ <para>
+ <code>monitor_unique_lock</code> is an extension of <classname>boost::unique_lock</classname>
+ from the
+ <ulink url="http://www.boost.org/doc/html/thread.html">Boost.Thread</ulink>
+ library. It extends the interface of
+ <classname>boost::unique_lock</classname> by adding <methodname>operator-></methodname>
+ and <methodname>operator*</methodname> methods, which permit access to
+ the object protected by the lock's associated monitor. This tight
+ coupling of locking with access helps insure
+ the monitor's mutex is always locked when the object it is protecting
+ is accessed.
+ </para>
+ <para>
+ The <code>MonitorType</code>
+ template type parameter may be one of the <classname>monitor</classname>
+ or <classname>monitor_ptr</classname> types.
+ </para>
+ <description>
+ <para>
+ See the documentation of boost::unique_lock in the Boost.Thread library for more information
+ about the unique_lock interface.
+ </para>
+ </description>
+ </description>
+ <access name="public">
+ <typedef name="monitor_type">
+ <type>MonitorType</type>
+ </typedef>
+ <typedef name="element_type">
+ <type>MonitorType::element_type</type>
+ <purpose>will additionally be const-qualified if MonitorType is "const monitor<T>"</purpose>
+ </typedef>
+ <method-group name="public boost::unique_lock interface">
+ <method name="lock">
+ <type>void</type>
+ </method>
+ <method name="move">
+ <type>boost::detail::thread_move_t<monitor_unique_lock></type>
+ </method>
+ <method name="mutex" cv="const">
+ <type>MonitorType *</type>
+ </method>
+ <method name="operator=">
+ <type>monitor_unique_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<monitor_unique_lock></paramtype>
+ </parameter>
+ </method>
+ <method name="operator=">
+ <type>monitor_unique_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_upgrade_lock</classname>></paramtype>
+ </parameter>
+ </method>
+ <method name="operator!" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="operator boost::detail::thread_move_t<monitor_unique_lock>">
+ </method>
+ <method name="operator unspecified_bool_type" cv="const">
+ </method>
+ <method name="owns_lock" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="release">
+ <type>MonitorType *</type>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>monitor_unique_lock &</paramtype>
+ </parameter>
+ </method>
+ <method name="timed_lock">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ <method name="try_lock">
+ <type>bool</type>
+ </method>
+ <method name="unlock">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="public member functions">
+ <method name="operator->" cv="const">
+ <type>element_type *</type>
+ <description>
+ <para>Provides access to the members of the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ <method name="operator*" cv="const">
+ <type>element_type &</type>
+ <description>
+ <para>Provides access to the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ </method-group>
+ <constructor specifiers="explicit">
+ <parameter name="mon">
+ <paramtype>MonitorType &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Calls lock(), acquiring exclusive ownership of <code>mon</code> (in the
+ sense of a lock having ownership of a mutex).
+ </para>
+ <para>
+ Internally, the monitor_unique_lock stores a <classname>monitor_ptr</classname>
+ to use as a reference to the object protected by the <code>mon</code> argument. Thus the
+ monitor_unique_lock shares ownership (in the <code>shared_ptr</code> sense)
+ and may safely outlive the <code>mon</code> object.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <parameter name="mon">
+ <paramtype>MonitorType &</paramtype>
+ </parameter>
+ <parameter name="arg">
+ <paramtype>const T &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ This constructor corresponds to all the 2 argument constructors of boost::unique_lock.
+ The second argument may thus be of type <classname>boost::adopt_lock_t</classname>,
+ <classname>boost::defer_lock_t</classname>, <classname>boost::try_to_lock_t</classname>,
+ or <classname>boost::system_time</classname>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<monitor_unique_lock></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_upgrade_lock</classname><MonitorType> ></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor. The upgrade_lock is upgraded to a unique_lock as it is moved into <code>*this</code>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <description>
+ <para>
+ The default constructor creates an empty lock that is not associated with any monitor object.
+ The empty lock can only be made useful by moving another another lock into it.
+ </para>
+ </description>
+ </constructor>
+ <destructor>
+ <description>
+ <para>If <code>owns_lock()</code>, calls <code>unlock()</code>.</para>
+ </description>
+ </destructor>
+ </access>
+ <access name="private">
+ <copy-assignment>
+ <parameter name="other">
+ <paramtype>monitor_unique_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </copy-assignment>
+ <constructor>
+ <parameter name="other">
+ <paramtype>monitor_unique_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </constructor>
+ </access>
+ <free-function-group name="free functions">
+ <function name="move">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>boost::detail::thread_move_t<<classname>monitor_unique_lock</classname><Monitor> ></type>
+ <parameter name="lock">
+ <paramtype><classname>monitor_unique_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <returns><code>lock.move()</code></returns>
+ </function>
+ <function name="swap">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>void</type>
+ <parameter name="lock_a">
+ <paramtype><classname>monitor_unique_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <parameter name="lock_b">
+ <paramtype><classname>monitor_unique_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <effects><code>lock_a.swap(lock_b)</code></effects>
+ </function>
+ </free-function-group>
+ </class>
+ <class name="monitor_shared_lock">
+ <template>
+ <template-type-parameter name="MonitorType"/>
+ </template>
+ <purpose>shared_lock with monitor object access</purpose>
+ <description>
+ <para>
+ <code>monitor_shared_lock</code> is an extension of <classname>boost::shared_lock</classname>
+ from the
+ <ulink url="http://www.boost.org/doc/html/thread.html">Boost.Thread</ulink>
+ library. It extends the interface of
+ <classname>boost::shared_lock</classname> by adding <methodname>operator-></methodname>
+ and <methodname>operator*</methodname> methods, which permit access to
+ the object protected by the lock's associated monitor. This tight
+ coupling of locking with access helps insure
+ the monitor's mutex is always locked when the object it is protecting
+ is accessed.
+ </para>
+ <para>
+ Unlike <classname>monitor_unique_lock</classname>, the <methodname>operator-></methodname>
+ and <methodname>operator*</methodname> of <code>monitor_shared_lock</code>
+ only permit <code>const</code>
+ access to the associated object. This helps prevent unintended
+ modification of the object while only holding a shared_lock.
+ </para>
+ <para>
+ The <code>MonitorType</code>
+ template type parameter may be one of the <classname>monitor</classname>
+ or <classname>monitor_ptr</classname> types.
+ </para>
+ <description>
+ <para>
+ See the documentation of boost::shared_lock in the Boost.Thread library for more information
+ about the shared_lock interface.
+ </para>
+ </description>
+ </description>
+ <access name="public">
+ <typedef name="monitor_type">
+ <type>MonitorType</type>
+ </typedef>
+ <typedef name="element_type">
+ <type>MonitorType::element_type</type>
+ <purpose>will additionally be const-qualified if MonitorType is "const monitor<T>"</purpose>
+ </typedef>
+ <method-group name="public boost::shared_lock interface">
+ <method name="lock">
+ <type>void</type>
+ </method>
+ <method name="move">
+ <type>boost::detail::thread_move_t<monitor_shared_lock></type>
+ </method>
+ <method name="mutex" cv="const">
+ <type>MonitorType *</type>
+ </method>
+ <method name="operator=">
+ <type>monitor_shared_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<monitor_shared_lock></paramtype>
+ </parameter>
+ </method>
+ <method name="operator=">
+ <type>monitor_shared_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_upgrade_lock</classname>></paramtype>
+ </parameter>
+ </method>
+ <method name="operator=">
+ <type>monitor_shared_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_unique_lock</classname>></paramtype>
+ </parameter>
+ </method>
+ <method name="operator!" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="operator boost::detail::thread_move_t<monitor_shared_lock>">
+ </method>
+ <method name="operator unspecified_bool_type" cv="const">
+ </method>
+ <method name="owns_lock" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="release">
+ <type>MonitorType *</type>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>monitor_shared_lock &</paramtype>
+ </parameter>
+ </method>
+ <method name="timed_lock">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ <method name="try_lock">
+ <type>bool</type>
+ </method>
+ <method name="unlock">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="public member functions">
+ <method name="operator->" cv="const">
+ <type>const element_type *</type>
+ <description>
+ <para>Provides <code>const</code> access to the members of the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ <method name="operator*" cv="const">
+ <type>const element_type &</type>
+ <description>
+ <para>Provides <code>const</code> access to the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ </method-group>
+ <constructor specifiers="explicit">
+ <parameter name="mon">
+ <paramtype>MonitorType &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Calls lock(), acquiring shared ownership of <code>mon</code>
+ (in the sense of a lock having ownership of a mutex).
+ </para>
+ <para>
+ Internally, the monitor_shared_lock stores a <classname>monitor_ptr</classname>
+ to use as a reference to the object protected by the <code>mon</code> argument. Thus the
+ monitor_shared_lock shares ownership (in the <code>shared_ptr</code> sense)
+ and may safely outlive the <code>mon</code> object.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <parameter name="mon">
+ <paramtype>MonitorType &</paramtype>
+ </parameter>
+ <parameter name="arg">
+ <paramtype>const T &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ This constructor corresponds to all the 2 argument constructors of boost::shared_lock.
+ The second argument may thus be of type <classname>boost::adopt_lock_t</classname>,
+ <classname>boost::defer_lock_t</classname>, <classname>boost::try_to_lock_t</classname>,
+ or <classname>boost::system_time</classname>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<monitor_shared_lock></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_upgrade_lock</classname><MonitorType> ></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_unique_lock</classname><MonitorType> ></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor. The unique_lock is downgraded to a shared_lock as it is moved into <code>*this</code>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <description>
+ <para>
+ The default constructor creates an empty lock that is not associated with any monitor object.
+ The empty lock can only be made useful by moving another another lock into it.
+ </para>
+ </description>
+ </constructor>
+ <destructor>
+ <description>
+ <para>If <code>owns_lock()</code>, calls <code>unlock()</code>.</para>
+ </description>
+ </destructor>
+ </access>
+ <access name="private">
+ <copy-assignment>
+ <parameter name="other">
+ <paramtype>monitor_shared_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </copy-assignment>
+ <constructor>
+ <parameter name="other">
+ <paramtype>monitor_shared_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </constructor>
+ </access>
+ <free-function-group name="free functions">
+ <function name="move">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>boost::detail::thread_move_t<<classname>monitor_shared_lock</classname><Monitor> ></type>
+ <parameter name="lock">
+ <paramtype><classname>monitor_shared_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <returns><code>lock.move()</code></returns>
+ </function>
+ <function name="swap">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>void</type>
+ <parameter name="lock_a">
+ <paramtype><classname>monitor_shared_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <parameter name="lock_b">
+ <paramtype><classname>monitor_shared_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <effects><code>lock_a.swap(lock_b)</code></effects>
+ </function>
+ </free-function-group>
+ </class>
+ <class name="monitor_upgrade_lock">
+ <template>
+ <template-type-parameter name="MonitorType"/>
+ </template>
+ <purpose>upgrade_lock with monitor object access</purpose>
+ <description>
+ <para>
+ <code>monitor_upgrade_lock</code> is an extension of <classname>boost::upgrade_lock</classname>
+ from the
+ <ulink url="http://www.boost.org/doc/html/thread.html">Boost.Thread</ulink>
+ library. It extends the interface of
+ <classname>boost::upgrade_lock</classname> by adding <methodname>operator-></methodname>
+ and <methodname>operator*</methodname> methods, which permit access to
+ the object protected by the lock's associated monitor. This tight
+ coupling of locking with access helps insure
+ the monitor's mutex is always locked when the object it is protecting
+ is accessed.
+ </para>
+ <para>
+ Like <classname>monitor_shared_lock</classname>, the <methodname>operator-></methodname>
+ and <methodname>operator*</methodname> of <code>monitor_upgrade_lock</code>
+ only permit <code>const</code>
+ access to the associated object. This helps prevent unintended
+ modification of the object while only holding a shared lock. Non-const
+ access to the associated object may be obtained by upgrading
+ to a unique lock.
+ </para>
+ <para>
+ The <code>MonitorType</code>
+ template type parameter may be one of the <classname>monitor</classname>
+ or <classname>monitor_ptr</classname> types.
+ </para>
+ <description>
+ <para>
+ See the documentation of boost::upgrade_lock in the Boost.Thread library for more information
+ about the upgrade_lock interface.
+ </para>
+ </description>
+ </description>
+ <access name="public">
+ <typedef name="monitor_type">
+ <type>MonitorType</type>
+ </typedef>
+ <typedef name="element_type">
+ <type>MonitorType::element_type</type>
+ <purpose>will additionally be const-qualified if MonitorType is "const monitor<T>"</purpose>
+ </typedef>
+ <method-group name="public boost::upgrade_lock interface">
+ <method name="lock">
+ <type>void</type>
+ </method>
+ <method name="move">
+ <type>boost::detail::thread_move_t<monitor_upgrade_lock></type>
+ </method>
+ <method name="mutex" cv="const">
+ <type>MonitorType *</type>
+ </method>
+ <method name="operator=">
+ <type>monitor_upgrade_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<monitor_upgrade_lock></paramtype>
+ </parameter>
+ </method>
+ <method name="operator=">
+ <type>monitor_upgrade_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_unique_lock</classname>></paramtype>
+ </parameter>
+ </method>
+ <method name="operator!" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="operator boost::detail::thread_move_t<monitor_upgrade_lock>">
+ </method>
+ <method name="operator unspecified_bool_type" cv="const">
+ </method>
+ <method name="owns_lock" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="release">
+ <type>MonitorType *</type>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>monitor_upgrade_lock &</paramtype>
+ </parameter>
+ </method>
+ <method name="timed_lock">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ <method name="try_lock">
+ <type>bool</type>
+ </method>
+ <method name="unlock">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="public member functions">
+ <method name="operator->" cv="const">
+ <type>const element_type *</type>
+ <description>
+ <para>Provides <code>const</code> access to the members of the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ <method name="operator*" cv="const">
+ <type>const element_type &</type>
+ <description>
+ <para>Provides <code>const</code> access to the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ </method-group>
+ <constructor specifiers="explicit">
+ <parameter name="mon">
+ <paramtype>MonitorType &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Calls lock(), acquiring upgrade ownership of <code>mon</code>
+ (in the sense of a lock having ownership of a mutex).
+ </para>
+ <para>
+ Internally, the monitor_upgrade_lock stores a <classname>monitor_ptr</classname>
+ to use as a reference to the object protected by the <code>mon</code> argument. Thus the
+ monitor_upgrade_lock shares ownership (in the <code>shared_ptr</code> sense)
+ and may safely outlive the <code>mon</code> object.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="T"/>
+ </template>
+ <parameter name="mon">
+ <paramtype>MonitorType &</paramtype>
+ </parameter>
+ <parameter name="arg">
+ <paramtype>const T &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ This constructor corresponds to all the 2 argument constructors of boost::upgrade_lock.
+ The second argument may thus be of type <classname>boost::adopt_lock_t</classname>,
+ <classname>boost::defer_lock_t</classname>, <classname>boost::try_to_lock_t</classname>,
+ or <classname>boost::system_time</classname>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<monitor_upgrade_lock></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<<classname>monitor_unique_lock</classname><MonitorType> ></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor. The unique_lock is downgraded to a upgrade_lock as it is moved into <code>*this</code>.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <description>
+ <para>
+ The default constructor creates an empty lock that is not associated with any monitor object.
+ The empty lock can only be made useful by moving another another lock into it.
+ </para>
+ </description>
+ </constructor>
+ <destructor>
+ <description>
+ <para>If <code>owns_lock()</code>, calls <code>unlock()</code>.</para>
+ </description>
+ </destructor>
+ </access>
+ <access name="private">
+ <copy-assignment>
+ <parameter name="other">
+ <paramtype>monitor_upgrade_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </copy-assignment>
+ <constructor>
+ <parameter name="other">
+ <paramtype>monitor_upgrade_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </constructor>
+ </access>
+ <free-function-group name="free functions">
+ <function name="move">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>boost::detail::thread_move_t<<classname>monitor_upgrade_lock</classname><Monitor> ></type>
+ <parameter name="lock">
+ <paramtype><classname>monitor_upgrade_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <returns><code>lock.move()</code></returns>
+ </function>
+ <function name="swap">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>void</type>
+ <parameter name="lock_a">
+ <paramtype><classname>monitor_upgrade_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <parameter name="lock_b">
+ <paramtype><classname>monitor_upgrade_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <effects><code>lock_a.swap(lock_b)</code></effects>
+ </function>
+ </free-function-group>
+ </class>
+ <class name="monitor_upgrade_to_unique_lock">
+ <template>
+ <template-type-parameter name="MonitorType"/>
+ </template>
+ <purpose>upgrade_to_unique_lock with monitor object access</purpose>
+ <description>
+ <para>
+ <code>monitor_upgrade_to_unique_lock</code> is an extension of <classname>boost::upgrade_to_unique_lock</classname>
+ from the
+ <ulink url="http://www.boost.org/doc/html/thread.html">Boost.Thread</ulink>
+ library. It extends the interface of
+ <classname>boost::upgrade_to_unique_lock</classname> by adding <methodname>operator-></methodname>
+ and <methodname>operator*</methodname> methods, which permit access to
+ the object protected by the lock's associated monitor. This tight
+ coupling of locking with access helps insure
+ the monitor's mutex is always locked when the object it is protecting
+ is accessed.
+ </para>
+ <para>
+ The <code>MonitorType</code>
+ template type parameter may be one of the <classname>monitor</classname>
+ or <classname>monitor_ptr</classname> types.
+ </para>
+ <description>
+ <para>
+ See the documentation of boost::upgrade_to_unique_lock in the Boost.Thread library for more information
+ about the upgrade_to_unique_lock interface.
+ </para>
+ </description>
+ </description>
+ <access name="public">
+ <typedef name="monitor_type">
+ <type>MonitorType</type>
+ </typedef>
+ <typedef name="element_type">
+ <type>MonitorType::element_type</type>
+ <purpose>will additionally be const-qualified if MonitorType is "const monitor<T>"</purpose>
+ </typedef>
+ <method-group name="public boost::upgrade_to_unique_lock interface">
+ <method name="move">
+ <type>boost::detail::thread_move_t<monitor_upgrade_to_unique_lock></type>
+ </method>
+ <method name="operator=">
+ <type>monitor_upgrade_to_unique_lock &</type>
+ <parameter>
+ <paramtype>boost::detail::thread_move_t<monitor_upgrade_to_unique_lock></paramtype>
+ </parameter>
+ </method>
+ <method name="operator!" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="operator boost::detail::thread_move_t<monitor_upgrade_to_unique_lock>">
+ </method>
+ <method name="operator unspecified_bool_type" cv="const">
+ </method>
+ <method name="owns_lock" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>monitor_upgrade_to_unique_lock &</paramtype>
+ </parameter>
+ </method>
+ </method-group>
+ <method-group name="public member functions">
+ <method name="operator->" cv="const">
+ <type>element_type *</type>
+ <description>
+ <para>Provides access to the members of the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ <method name="operator*" cv="const">
+ <type>element_type &</type>
+ <description>
+ <para>Provides access to the object protected by the lock's associated
+ monitor.
+ </para>
+ </description>
+ <throws>
+ <para>
+ <classname>boost::lock_error</classname> if <code>owns_lock() != true</code>.
+ </para>
+ </throws>
+ </method>
+ </method-group>
+ <constructor specifiers="explicit">
+ <parameter name="lock">
+ <paramtype>monitor_upgrade_lock<MonitorType> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ If <code>lock.owns_lock()</code>, then <code>*this</code> takes exclusive ownership
+ of the upgrade lock's mutex.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>boost::detail::thread_move_t<monitor_upgrade_to_unique_lock></paramtype>
+ </parameter>
+ <description>
+ <para>
+ Move constructor.
+ </para>
+ </description>
+ </constructor>
+ <destructor>
+ <description>
+ <para>If <code>owns_lock()</code>, releases exclusive ownership and
+ returns upgrade ownership to the upgrade_lock <code>*this</code> was
+ constructed from.
+ </para>
+ </description>
+ </destructor>
+ </access>
+ <access name="private">
+ <copy-assignment>
+ <parameter name="other">
+ <paramtype>monitor_upgrade_to_unique_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </copy-assignment>
+ <constructor>
+ <parameter name="other">
+ <paramtype>monitor_upgrade_to_unique_lock &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Locks are moveable but not copyable.
+ </para>
+ </description>
+ </constructor>
+ </access>
+ <free-function-group name="free functions">
+ <function name="move">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>boost::detail::thread_move_t<<classname>monitor_upgrade_to_unique_lock</classname><Monitor> ></type>
+ <parameter name="lock">
+ <paramtype><classname>monitor_upgrade_to_unique_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <returns><code>lock.move()</code></returns>
+ </function>
+ <function name="swap">
+ <template>
+ <template-type-parameter name="Monitor"/>
+ </template>
+ <type>void</type>
+ <parameter name="lock_a">
+ <paramtype><classname>monitor_upgrade_to_unique_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <parameter name="lock_b">
+ <paramtype><classname>monitor_upgrade_to_unique_lock</classname><Monitor> &</paramtype>
+ </parameter>
+ <effects><code>lock_a.swap(lock_b)</code></effects>
+ </function>
+ </free-function-group>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/monitor_ptr_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/monitor_ptr_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,498 @@
+<header name="poet/monitor_ptr.hpp">
+ <namespace name="poet">
+ <class name="monitor_ptr">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Mutex">
+ <default>boost::mutex</default>
+ </template-type-parameter>
+ </template>
+ <purpose>A smart pointer which provides automatically locked access to an object.</purpose>
+ <description>
+ <para>
+ <code>monitor_ptr</code> allows for the easy creation of monitor objects. A
+ <code>monitor_ptr</code> provides automatically locked access to an object's members
+ when they are accessed through the overloaded <methodname>operator-></methodname>,
+ or alternatively through one of the lock classes from
+ <link linkend="header.poet.monitor_locks.hpp">poet/monitor_locks.hpp</link>.
+ It is based in part on ideas taken from
+ <ulink url="http://www.research.att.com/~bs/wrapper.pdf">"Wrapping C++ Member Function Calls"</ulink>
+ by Bjarne Stroustroup and <ulink url="http://www.cs.wustl.edu/~schmidt/PDF/monitor.pdf">"Monitor Object:
+ An Object Behavioral Pattern for Concurrent Programming"</ulink> by Douglas C. Schmidt.
+ </para>
+ <para>
+ Although any object may be passed to a <code>monitor_ptr</code>, special support is provided
+ for classes derived from <classname>monitor_base</classname>. This allows classes derived from
+ <classname>monitor_base</classname> to wait on conditions inside member function calls,
+ releasing the <code>monitor_ptr</code>'s mutex until the condition is met.
+ </para>
+ <para>
+ The <code>Mutex</code> template type parameter must model the <code>Lockable</code>
+ concept from the Boost.Thread library. The <code>monitor_ptr</code> itself models the
+ <code>Lockable</code> concept, and will also model any of the
+ <code>TimedLockable</code>, <code>SharedLockable</code>, or <code>UpgradeLockable</code>
+ concepts if the underlying <code>Mutex</code> template type supports them.
+ Note however, a <code>monitor_ptr</code> must not be empty when being used as
+ a mutex. An empty <code>monitor_ptr</code> will throw a
+ <classname>boost::lock_error</classname> if any attempt is made to use
+ <methodname>lock</methodname>, <methodname>unlock</methodname>, or any other
+ part of the <code>monitor_ptr</code> interface which models the Boost.Thread concepts.
+ </para>
+ <para>
+ The interfaces defined by the Boost.Thread mutex concepts should generally
+ not be used directly by the user. They are intended to be used by
+ scoped lock classes such as <classname>monitor_unique_lock</classname>,
+ which provide a safer means to perform locking.
+ See the "Mutex Concepts" documentation in the Boost.Thread library
+ for more information about the Lockable, etc. concepts.
+ </para>
+ <para>
+ Note that while <code>monitor_ptr</code> provides thread-safe access to the object
+ it is pointing at, it does not provide a strong thread-safety guarantee
+ for itself.
+ That is, a single
+ <code>monitor_ptr</code> object should not be modified concurrently by multiple
+ threads. Rather, each thread should be passed its own copy of the
+ <code>monitor_ptr</code> to use. The thread-safety guarantees of
+ <code>monitor_ptr</code> are similar to those provided by <classname>boost::shared_ptr</classname>.
+ </para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.monitor_demo.cpp">monitor_demo.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <classname>monitor</classname>: an alternative to the <code>monitor_ptr</code> class,
+ which stores its wrapped object by value instead of acting like a pointer.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <typedef name="element_type">
+ <type>T</type>
+ </typedef>
+ <typedef name="mutex_type">
+ <type>Mutex</type>
+ </typedef>
+ <method-group name="public member functions">
+ <method name="direct" cv="const">
+ <type>const boost::shared_ptr<T> &</type>
+ <description><para>Gives direct unlocked access to the underlying pointer.</para></description>
+ </method>
+ <method name="operator->" cv="const">
+ <type><classname>monitor_unique_lock</classname><const monitor_ptr></type>
+ <description>
+ <para>Returns a temporary <classname>monitor_unique_lock</classname> which
+ locks the <code>monitor_ptr</code>'s mutex.
+ The <code>operator->()</code> of the returned <classname>monitor_unique_lock</classname>
+ object will be
+ automatically called in turn (overloading <code>operator->()</code> is special in that way), which will
+ utimately result in a call of <code>operator->()</code> on the
+ <code>monitor_ptr</code>'s underlying pointer.
+ The mutex is automatically unlocked after the member access completes by the
+ <classname>monitor_unique_lock</classname>
+ destructor.
+ </para>
+ <para>
+ If more flexibility is desired, the lock types from
+ <link linkend="header.poet.monitor_locks.hpp">poet/monitor_locks.hpp</link>
+ provide alternatives to <code>monitor_ptr::operator-></code>.
+ </para>
+ </description>
+ </method>
+ <method name="operator bool" cv="const">
+ <description>
+ <para>
+ Conversion to <code>bool</code> results in <code>false</code> if the <code>monitor_ptr</code>'s underlying pointer
+ is null, <code>true</code> otherwise.
+ </para>
+ </description>
+ </method>
+ <overloaded-method name="reset">
+ <signature>
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <type>void</type>
+ <parameter name="pointer">
+ <paramtype>U*</paramtype>
+ </parameter>
+ </signature>
+ <signature>
+ <type>void</type>
+ <parameter name="smart_pointer">
+ <paramtype>const boost::shared_ptr<T> &</paramtype>
+ </parameter>
+ </signature>
+ <signature>
+ <type>void</type>
+ </signature>
+ <signature>
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>const monitor_ptr<U, Mutex> &</paramtype>
+ </parameter>
+ <parameter name="pointer">
+ <paramtype>T*</paramtype>
+ </parameter>
+ </signature>
+ <description>
+ <para>
+ Resets the <code>monitor_ptr</code>'s underlying pointer using the specified parameter(s).
+ A new mutex and condition are also created (except in the no-parameter case, where
+ they are simply deleted).
+ </para>
+ <para>
+ The overload which takes a <code>monitor_ptr</code> and
+ <code>T*</code> argument makes <code>*this</code> into an aliased <code>monitor_ptr</code>,
+ which shares ownership and its mutex with
+ <code>other</code>, but which points at the address given by <code>pointer</code>. See the
+ description of the <link linkend="monitor-ptr-constructor-aliasing">aliasing constructor</link>
+ for more information.
+ </para>
+ </description>
+ </overloaded-method>
+ <method name="swap">
+ <type>void</type>
+ <parameter name="other">
+ <paramtype>monitor_ptr &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Swaps <code>*this</code> and <code>other</code>.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread Lockable concept support">
+ <method name="lock" cv="const">
+ <type>void</type>
+ </method>
+ <method name="try_lock" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="unlock" cv="const">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread TimedLockable concept support">
+ <method name="timed_lock" cv="const">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t" cv="const">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread SharedLockable concept support">
+ <method name="lock_shared" cv="const">
+ <type>void</type>
+ </method>
+ <method name="try_lock_shared" cv="const">
+ <type>bool</type>
+ </method>
+ <method name="timed_lock_shared" cv="const">
+ <template>
+ <template-type-parameter name="Timeout"/>
+ </template>
+ <type>bool</type>
+ <parameter name="t" cv="const">
+ <paramtype>const Timeout &</paramtype>
+ </parameter>
+ </method>
+ <method name="unlock_shared" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_and_lock_shared" cv="const">
+ <type>void</type>
+ </method>
+ </method-group>
+ <method-group name="Boost.Thread UpgradeLockable concept support">
+ <method name="lock_upgrade" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade_and_lock" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_upgrade_and_lock_shared" cv="const">
+ <type>void</type>
+ </method>
+ <method name="unlock_and_lock_upgrade" cv="const">
+ <type>void</type>
+ </method>
+ </method-group>
+ <copy-assignment>
+ <parameter name="rhs">
+ <paramtype>const monitor_ptr &</paramtype>
+ </parameter>
+ <description>
+ <para>After assignment, the two <code>monitor_ptr</code>s will share the same pointer,
+ mutex, and condition variable.
+ </para>
+ </description>
+ </copy-assignment>
+ <constructor>
+ <description>
+ <para>The default constructor creates an empty <code>monitor_ptr</code>.
+ </para>
+ </description>
+ </constructor>
+ <constructor specifiers="explicit">
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <parameter name="pointer">
+ <paramtype>U*</paramtype>
+ </parameter>
+ <description>
+ <para>Creates a <code>monitor_ptr</code> which wraps the specified pointer. The <code>monitor_ptr</code>
+ internally stores <code>pointer</code> in a <classname>boost::shared_ptr</classname>.
+ Thus the pointer will be automatically
+ deleted when the last copy of this <code>monitor_ptr</code> is destroyed.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="smart_pointer">
+ <paramtype>boost::shared_ptr<T></paramtype>
+ </parameter>
+ <description>
+ <para>Creates a <code>monitor_ptr</code> which wraps the specified pointer.
+ This constructor allows the <code>monitor_ptr</code> to be initialized with
+ a <classname>boost::shared_ptr</classname> that has a custom deleter.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <parameter name="other">
+ <paramtype>const monitor_ptr &</paramtype>
+ </parameter>
+ <description>
+ <para>The copy constructor creates a <code>monitor_ptr</code> which shares the same pointer,
+ mutex, and condition as the original.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <parameter name="other">
+ <paramtype>const monitor_ptr<U, Mutex> &</paramtype>
+ </parameter>
+ <description>
+ <para>This constructor creates a <code>monitor_ptr</code> which shares the same pointer
+ (implicitly converted), mutex, and condition as the original.
+ </para>
+ </description>
+ </constructor>
+ <constructor>
+ <template>
+ <template-type-parameter name="U"/>
+ </template>
+ <parameter name="other">
+ <paramtype>const monitor_ptr<U, Mutex> &</paramtype>
+ </parameter>
+ <parameter name="pointer">
+ <paramtype>T*</paramtype>
+ </parameter>
+ <description>
+ <para id="monitor-ptr-constructor-aliasing">
+ This is an aliasing constructor, similar in function to the aliasing constructor of <code>shared_ptr</code>.
+ It creates a <code>monitor_ptr</code> which shares
+ ownership and uses the same mutex as <code>other</code>, but which points at the
+ object specified by <code>pointer</code> when dereferenced. The types <code>T</code> and
+ <code>U</code> may be unrelated.
+ It is useful for creating
+ <code>monitor_ptr</code>s to objects which are only indirectly owned by a <code>monitor_ptr</code>,
+ for example:
+<programlisting>struct coordinates
+{
+ int x;
+ int y;
+};
+
+// ...
+
+poet::monitor_ptr<coordinates> coords(new coordinates());
+// x_mon shares ownership of coords object, but points at coords->x.
+// x_mon might be needed to pass the x member of the coords object to a function
+// expecting an argument of type poet::monitor_ptr<int>.
+poet::monitor_ptr<int> x_mon(coords, &coords->x);
+// the following block has the same effect as "coords->x = 5;"
+{
+ poet::monitor_unique_lock<monitor_ptr<int> > x_lock(x_mon);
+ *x_lock = 5;
+}</programlisting>
+ </para>
+ </description>
+ </constructor>
+ <destructor specifiers="virtual">
+ <description>
+ <para>A <code>monitor_ptr</code> and all its copies share ownership of an underlying pointer,
+ mutex, and condition variable. The pointer, mutex, and condition are
+ deleted when the last copy of the
+ <code>monitor_ptr</code> is destroyed. The deleter for the underlying pointer may
+ be customized by using the constructor which takes a <classname>boost::shared_ptr</classname>
+ as its parameter.
+ </para>
+ </description>
+ </destructor>
+ </access>
+ <free-function-group name="free functions: casts">
+ <function name="static_pointer_cast">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="Mutex"/>
+ </template>
+ <type>monitor_ptr<T, Mutex></type>
+ <parameter name="p">
+ <paramtype>const <classname>monitor_ptr</classname><U, Mutex> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Casts a <code>monitor_ptr</code> by applying <code>boost::static_pointer_cast<U></code>
+ to the <code>monitor_ptr</code>'s
+ underlying <code>shared_ptr</code>.
+ </para>
+ </description>
+ </function>
+ <function name="dynamic_pointer_cast">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="Mutex"/>
+ </template>
+ <type>monitor_ptr<T, Mutex></type>
+ <parameter name="p">
+ <paramtype>const <classname>monitor_ptr</classname><U, Mutex> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Casts a <code>monitor_ptr</code> by applying <code>boost::dynamic_pointer_cast<U></code>
+ to the <code>monitor_ptr</code>'s
+ underlying <code>shared_ptr</code>.
+ </para>
+ </description>
+ </function>
+ <function name="const_pointer_cast">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="Mutex"/>
+ </template>
+ <type>monitor_ptr<T, Mutex></type>
+ <parameter name="p">
+ <paramtype>const <classname>monitor_ptr</classname><U, Mutex> &</paramtype>
+ </parameter>
+ <description>
+ <para>
+ Casts a <code>monitor_ptr</code> by applying <code>boost::const_pointer_cast<U></code>
+ to the <code>monitor_ptr</code>'s
+ underlying <code>shared_ptr</code>.
+ </para>
+ </description>
+ </function>
+ </free-function-group>
+ <free-function-group name="free functions: comparison">
+ <function name="operator==">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="MutexA"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="MutexB"/>
+ </template>
+ <type>bool</type>
+ <parameter name="a">
+ <paramtype>const <classname>monitor_ptr</classname><T, MutexT> &</paramtype>
+ </parameter>
+ <parameter name="b">
+ <paramtype>const <classname>monitor_ptr</classname><U, MutexU> &</paramtype>
+ </parameter>
+ <returns>
+ <para>
+ Returns the result of applying <code>operator==</code> to the underlying <code>shared_ptr</code>s
+ of the two <code>monitor_ptr</code> arguments.
+ </para>
+ </returns>
+ </function>
+ <function name="operator!=">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="MutexA"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="MutexB"/>
+ </template>
+ <type>bool</type>
+ <parameter name="a">
+ <paramtype>const <classname>monitor_ptr</classname><T, MutexT> &</paramtype>
+ </parameter>
+ <parameter name="b">
+ <paramtype>const <classname>monitor_ptr</classname><U, MutexU> &</paramtype>
+ </parameter>
+ <returns>
+ <para>
+ Returns the result of applying <code>operator!=</code> to the underlying <code>shared_ptr</code>s
+ of the two <code>monitor_ptr</code> arguments.
+ </para>
+ </returns>
+ </function>
+ <function name="operator<">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="MutexA"/>
+ <template-type-parameter name="U"/>
+ <template-type-parameter name="MutexB"/>
+ </template>
+ <type>bool</type>
+ <parameter name="a">
+ <paramtype>const <classname>monitor_ptr</classname><T, MutexT> &</paramtype>
+ </parameter>
+ <parameter name="b">
+ <paramtype>const <classname>monitor_ptr</classname><U, MutexU> &</paramtype>
+ </parameter>
+ <returns>
+ <para>
+ Returns the result of applying <code>operator<</code> to the underlying <code>shared_ptr</code>s
+ of the two <code>monitor_ptr</code> arguments.
+ </para>
+ </returns>
+ </function>
+ </free-function-group>
+ <free-function-group name="free function: swap">
+ <function name="swap">
+ <template>
+ <template-type-parameter name="T"/>
+ <template-type-parameter name="Mutex"/>
+ </template>
+ <parameter name="monitor0"><paramtype>monitor_ptr<T, Mutex> &</paramtype></parameter>
+ <parameter name="monitor1"><paramtype>monitor_ptr<T, Mutex> &</paramtype></parameter>
+ <type>void</type>
+ <description>
+ <para>
+ Swaps <code>monitor0</code> and <code>monitor1</code>. This
+ function is provided to
+ enhance efficiency with generic algorithms.
+ </para>
+ </description>
+ </function>
+ </free-function-group>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/mutex_grapher_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/mutex_grapher_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,198 @@
+<header name="poet/mutex_grapher.hpp">
+ <namespace name="poet">
+ <class name="mutex_grapher">
+ <purpose>Maintains a locking order graph for <classname>acyclic_mutex</classname>es.
+ </purpose>
+ <description>
+ <para>
+ The <code>mutex_grapher</code> class is a singleton which maintains a graph of
+ the locking order for the program's <classname>acyclic_mutex</classname>es.
+ It checks this graph to insure it has
+ a consistent locking order which cannot deadlock.
+ </para>
+ <para>
+ The class also provides information that may be useful in debugging any locking
+ order inconsistencies which are discovered. The user may examine the
+ <classname>locking_order_graph</classname>, output it to a graphviz file,
+ and examine the list of mutexes
+ currently locked by each thread. The user may also specify a custom handler to be called
+ in the event an inconsistency is detected.
+ </para>
+ <itemizedlist>
+ <title>Example Code</title>
+ <listitem>
+ <para>
+ <link linkend="poet.example.acyclic_mutex_demo.cpp">acyclic_mutex_demo.cpp</link>
+ </para>
+ </listitem>
+ </itemizedlist>
+ <itemizedlist>
+ <title>See also</title>
+ <listitem>
+ <para>
+ <classname>acyclic_mutex</classname>: a mutex wrapper whose locking events are
+ automatically tracked by <code>mutex_grapher</code>.
+ </para>
+ </listitem>
+ </itemizedlist>
+ </description>
+ <access name="public">
+ <struct name="vertex_properties">
+ <purpose>Bundled vertex properties for <classname>locking_order_graph</classname>.</purpose>
+ <description>
+ <para>
+ Each vertex in the <classname>locking_order_graph</classname> of the <classname>mutex_grapher</classname>
+ class has an object of this class associated with it as its bundled property.
+ For a vertex which represents a group of <classname>acyclic_mutex</classname>es
+ which share an equivalent key, then the <code>name</code> member is initialized by
+ passing the key though the formatted output operator <code>operator<<()</code>.
+ If the vertex represents a single key-less <classname>acyclic_mutex</classname>,
+ then <code>name</code> is initialized to the string "mutex" followed
+ by a decimal number obtained by passing the vertex's descriptor through
+ <code>operator<<()</code>.
+ </para>
+ <para>
+ The <code>name</code> member is used by <methodname>mutex_grapher::write_graphviz</methodname>
+ to label the vertexes in the graphviz output.
+ </para>
+ </description>
+ <data-member name="name">
+ <type>std::string</type>
+ </data-member>
+ </struct>
+ <struct name="edge_properties">
+ <purpose>Bundled edge properties for <classname>locking_order_graph</classname>.</purpose>
+ <description>
+ <para>
+ Each edge in the <classname>locking_order_graph</classname> of the <classname>mutex_grapher</classname>
+ class has an object of this class associated with it as its bundled property.
+ If the <classname>locking_order_graph</classname> is acyclic immeditately after the edge was added
+ to the graph, then the <code>locking_order_violation</code> member will be
+ <code>false</code>. If the graph has a cycle, then the <code>locking_order_violation</code>
+ member will be <code>true</code>.
+ </para>
+ <para>
+ The <code>locking_order_violation</code> member is used by <methodname>mutex_grapher::write_graphviz</methodname>
+ to color the edges (red for violations, black otherwise) in the graphviz output.
+ </para>
+ </description>
+ <data-member name="locking_order_violation"><type>bool</type></data-member>
+ </struct>
+ <typedef name="locking_order_graph">
+ <type>boost::adjacency_list<boost::setS, boost::vecS, boost::directedS, vertex_properties, edge_properties></type>
+ <description>
+ <para>
+ The <code>mutex_grapher</code> singleton contains one <code>locking_order_graph</code> object
+ which records all the locking order information for <classname>acyclic_mutex</classname>es.
+ Read access to the graph is provided through <methodname>mutex_grapher::graph</methodname>().
+ </para>
+ <para>
+ Each vertex in the graph represents either a group of <classname>acyclic_mutex</classname>es
+ which all have equivalent keys, or a single default-constructed <classname>acyclic_mutex</classname>
+ (which has no key). A vertexes is added to the graph the first time one of its
+ associated mutexes is locked.
+ </para>
+ <para>
+ Each edge in the graph represents an established locking order between
+ two vertices. When a thread attempts to lock an <classname>acyclic_mutex</classname>
+ while already holding a lock on one or more <classname>acyclic_mutex</classname>es,
+ a directed edge is added to the graph (if the edge in question does not already exist).
+ The edge is directed from the vertex of the most recently locked mutex towards the
+ vertex of the new mutex the thread is attempting to lock. After each new edge
+ is added, the locking order graph is checked for cycles.
+ As long as the graph remains free of cycles, the locking order
+ among the program's <classname>acyclic_mutex</classname>es is valid and will not
+ result in deadlock.
+ </para>
+ <para>
+ See the documentation of the Boost Graph Library for more information on <classname>boost::adjacency_list</classname>.
+ </para>
+ </description>
+ </typedef>
+ <typedef name="mutex_list_type"><type>std::list<const <classname>acyclic_mutex_base</classname> *></type></typedef>
+ <class name="unique_lock">
+ <inherit access="public">
+ <type><classname>monitor_unique_lock</classname><<classname>monitor_ptr</classname><<classname>mutex_grapher</classname>, boost::mutex> ></type>
+ </inherit>
+ <purpose>Provides locked access to the <classname>mutex_grapher</classname> singleton.</purpose>
+ <description>
+ <para>
+ This unique_lock class is default constructible (since there is only one mutex_grapher object),
+ and inherits from <classname>monitor_unique_lock</classname>.
+ Creating objects of this class is the only way to access the <classname>mutex_grapher</classname> singleton.
+ </para>
+ </description>
+ <access name="public">
+ <constructor>
+ <description>
+ <para>
+ Creates a <classname>monitor_unique_lock</classname> which provides access to the
+ mutex_grapher singleton.
+ </para>
+ </description>
+ </constructor>
+ </access>
+ </class>
+ <method-group name="public member functions">
+ <method name="graph" cv="const">
+ <type>const <classname>locking_order_graph</classname> &</type>
+ <description>
+ <para>
+ Provides access to the <classname>locking_order_graph</classname>.
+ </para>
+ </description>
+ </method>
+ <method name="locked_mutexes" cv="const">
+ <type>const <classname>mutex_list_type</classname> &</type>
+ <description>
+ <para>Returns a list of <classname>acyclic_mutex_base</classname> pointers to
+ the mutexes currently locked by the calling thread. The list is ordered in
+ the same order that the mutexes were locked. This list is thread-specific
+ data, and thus will vary depending on what thread this method is called from.
+ </para>
+ </description>
+ </method>
+ <method name="set_cycle_handler">
+ <template>
+ <template-type-parameter name="Func"/>
+ </template>
+ <type>void</type>
+ <parameter name="func">
+ <paramtype>Func</paramtype>
+ </parameter>
+ <description>
+ <para>
+ The function object <code>func</code> will be called (with no arguments)
+ when a cycle is detected in the <classname>locking_order_graph</classname>. The default cycle handler
+ prints a message to stderr, and then calls <code>abort()</code>.
+ </para>
+ </description>
+ </method>
+ <method name="write_graphviz" cv="const">
+ <type>void</type>
+ <parameter name="out_stream"><paramtype>std::ostream &</paramtype></parameter>
+ <description>
+ <para>
+ Calls <code>boost::write_graphviz</code>(), passing it the <code>out_stream</code>
+ parameter, and the <classname>locking_order_graph</classname>. The vertices are labeled with the <code>name</code>
+ member of the graph's bundled <classname alt="mutex_grapher::vertex_properties">vertex_properties</classname>.
+ The edges are colored black
+ if the <code>locking_order_violation</code> member of the the graph's bundled
+ <classname alt="mutex_grapher::edge_properties">edge_properties</classname>
+ is false, and red if it is true.
+ </para>
+ </description>
+ </method>
+ </method-group>
+ </access>
+ <access name="private">
+ <constructor>
+ <description>
+ <para>Private constructor. The <code>mutex_grapher</code> singleton may only
+ be accessed by creating a <classname>mutex_grapher::unique_lock</classname> object.</para>
+ </description>
+ </constructor>
+ </access>
+ </class>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/boostbook/mutex_properties_hpp.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/boostbook/mutex_properties_hpp.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,49 @@
+<header name="poet/mutex_properties.hpp">
+ <namespace name="poet">
+ <class name="mutex_properties">
+ <template>
+ <template-type-parameter name="Mutex">
+ </template-type-parameter>
+ </template>
+ <purpose>A class for discovering the properties of a type which models one of
+ the mutex concepts defined by the Boost Thread library.</purpose>
+ <description>
+ <para>
+ The <code>mutex_properties</code> class is used by libpoet to discover the properties
+ of mutex types passed as template type parameters to
+ <classname>acyclic_mutex</classname>. These properties are used internally to
+ perform partial template specializations according to the properties of the
+ mutex being used.
+ </para>
+ <para>
+ Specializations of <code>mutex_properties</code> are provided by libpoet
+ for all the mutex
+ types defined by the Boost Thread library, as well as all mutex types defined
+ by libpoet itself. If you wish to use some other custom class with
+ <classname>acyclic_mutex</classname>
+ as the Mutex template type parameter, you will need to also define a
+ specialization of <code>poet::mutex_properties</code> for your custom
+ mutex class.
+ </para>
+ </description>
+ <access name="public">
+ <static-constant name="recursive">
+ <type>bool</type>
+ <default><emphasis>varies</emphasis></default>
+ <purpose><code>true</code> if the <code>Mutex</code> template type parameter is a recursive mutex.</purpose>
+ </static-constant>
+ <static-constant name="model">
+ <type>enum <enumname>mutex_model</enumname></type>
+ <default><emphasis>varies</emphasis></default>
+ <purpose>Specifies the one of the mutex concepts from Boost.Thread (version 1.35.0 or later).</purpose>
+ </static-constant>
+ </access>
+ </class>
+ <enum name="mutex_model">
+ <enumvalue name="Lockable"/>
+ <enumvalue name="TimedLockable"/>
+ <enumvalue name="SharedLockable"/>
+ <enumvalue name="UpgradeLockable"/>
+ </enum>
+ </namespace>
+</header>
Added: sandbox/libpoet/trunk/doc/javascript/common.js
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/common.js 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,35 @@
+/*===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+===========================================================================*/
+
+/* Common Functions and configuration */
+
+(function() {
+
+// Add the base url if it is relative
+
+function format_url(sUrl,sBaseUrl)
+{
+ return ( sUrl.substring(0,7) == 'http://' ) ? sUrl : ( sBaseUrl + sUrl );
+}
+
+// Add '/' to the end if necesary
+
+function format_base_url(sBaseUrl)
+{
+ return ( sBaseUrl!='' && sBaseUrl.charAt(sBaseUrl.length-1)!='/' ) ?
+ ( sBaseUrl + '/' ) : sBaseUrl;
+}
+
+// Public Interface
+
+boostscript.common.format_url = format_url;
+boostscript.common.format_base_url = format_base_url;
+
+boostscript.common.loaded = true;
+
+})();
Added: sandbox/libpoet/trunk/doc/javascript/cookies.js
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/cookies.js 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,53 @@
+/*===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+===========================================================================*/
+
+
+(function() {
+
+/* Based on http://www.quirksmode.org/js/cookies.html */
+
+function create_cookie( sName, sValue, nDays )
+{
+ var sExpires;
+ if( nDays )
+ {
+ var dDate = new Date();
+ dDate.setTime( dDate.getTime() + ( nDays * 24*60*60*1000 ) );
+ sExpires = "; expires=" + dDate.toGMTString();
+ }
+ else
+ {
+ sExpires = "";
+ }
+ document.cookie = sName + "=" + sValue + sExpires + "; path=/";
+}
+
+function read_cookie(sName)
+{
+ var sNameEq = sName + "=";
+ var aCookies = document.cookie.split(';');
+ for(var i=0, len = aCookies.length ; i < len ; i++ )
+ {
+ var oCookie = aCookies[i].replace(/^\s+/g, "");
+ if( oCookie.indexOf(sNameEq) == 0 )
+ {
+ return oCookie.substring( sNameEq.length, oCookie.length );
+ }
+ }
+ return null;
+}
+
+// Public Interface
+
+boostscript.cookies.create = create_cookie;
+boostscript.cookies.read = read_cookie;
+
+boostscript.cookies.loaded = true;
+
+})();
+
Added: sandbox/libpoet/trunk/doc/javascript/load_file.js
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/load_file.js 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,88 @@
+/*===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+===========================================================================*/
+
+(function() {
+
+// File Cache
+
+var file_cache = new Array();
+
+// Load an xml file, and pass it to the callback function when it is ready
+
+function load_xml(sUrl, oCallback, bCached )
+{
+ if( bCached )
+ {
+ var oXml = file_cache[sUrl];
+ if( oXml )
+ {
+ oCallback(oXml);
+ return;
+ }
+ }
+ function add_to_cache( oXml )
+ {
+ if( bCached )
+ {
+ file_cache[sUrl] = oXml;
+ }
+ }
+
+
+ if (document.implementation && document.implementation.createDocument)
+ {
+ oXml = document.implementation.createDocument("", "", null);
+ oXml.onload = function() {
+ add_to_cache(oXml);
+ oCallback(oXml);
+ };
+ oXml.load(sUrl);
+
+ }
+ else if (window.ActiveXObject)
+ {
+ oXml = new ActiveXObject("Microsoft.XMLDOM");
+ oXml.onreadystatechange = function ()
+ {
+ if (oXml.readyState == 4)
+ {
+ add_to_cache(oXml);
+ oCallback(oXml);
+ }
+ };
+ oXml.load(sUrl);
+ }
+ else if( window.XMLHttpRequest )
+ {
+ var XMLHttpRequestObject = new XMLHttpRequest();
+ XMLHttpRequestObject.open("GET", sUrl);
+ XMLHttpRequestObject.onreadystatechange = function()
+ {
+ if (XMLHttpRequestObject.readyState == 4)
+ {
+ var oXml = XMLHttpRequestObject.responseXML;
+ add_to_cache(oXml);
+ oCallback(oXml);
+ delete XMLHttpRequestObject;
+ }
+ }
+ XMLHttpRequestObject.send(null);
+ }
+ else
+ {
+ // unsupported browser
+ }
+}
+
+// Public Interface
+
+boostscript.load_file.load_xml = load_xml;
+
+boostscript.load_file.loaded = true;
+
+})();
Added: sandbox/libpoet/trunk/doc/javascript/main.js
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/main.js 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,176 @@
+/*===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+===========================================================================*/
+
+var boostscript;
+
+(function() {
+
+function Namespace(oLibrary,nId,sFilePath,aInclude)
+{
+ this.id = nId; this.path = sFilePath;
+ this.used = false; this.loaded = false;
+
+ this.include = aInclude ? aInclude : new Array();
+ oLibrary.namespace[nId] = this;
+}
+
+function boostscript_library()
+{
+ this.namespace = new Array();
+ var id = 0;
+
+/************************************************************************/
+/* Modify this section to add new components to the library */
+/* Do not forget to add an 'add_component' call in the listing */
+/* below including the file dependencies */
+/* */
+/* */
+
+ this.common = new Namespace(this,id++,
+ 'common.js'
+ );
+
+ this.load_file = new Namespace(this,id++,
+ 'load_file.js'
+ );
+
+ this.cookies = new Namespace(this,id++,
+ 'cookies.js'
+ );
+
+ this.nested_links = new Namespace(this,id++,
+ 'nested_links.js',
+ new Array( // Requires
+ this.common,
+ this.load_file
+ )
+ );
+
+ this.style_switcher = new Namespace(this,id++,
+ 'style_switcher.js',
+ new Array( // Requires
+ this.common,
+ this.cookies,
+ this.load_file
+ )
+ );
+
+/* */
+/* */
+/************************************************************************/
+
+}
+
+function safari_browser()
+{
+ return ( navigator.vendor.indexOf('Apple') != -1 );
+}
+
+function include_components( aUsedComponents, sUserBaseUrl )
+{
+ insert_needed_includes( boostscript.namespace, aUsedComponents,
+ format_base_url(sUserBaseUrl) );
+}
+
+function insert_needed_includes( aComponents, aUsedComponents, sBaseUrl )
+{
+ for(var i = 0, len = aUsedComponents.length; i < len; i++)
+ {
+ find_needed_includes( aUsedComponents[i] );
+ }
+
+ if( safari_browser() )
+ {
+ write_insertion_included_scripts( sBaseUrl );
+ }
+ else
+ {
+ dom_insertion_included_scripts( sBaseUrl );
+ }
+}
+
+function find_needed_includes( oComp )
+{
+ if( oComp.used ) return;
+ oComp.used = true;
+ var aInclude = oComp.include;
+ for(var i = 0, len = aInclude.length; i < len; i++ )
+ {
+ find_needed_includes( aInclude[i] );
+ }
+}
+
+function dom_insertion_included_scripts( sBaseUrl )
+{
+ var namespace = boostscript.namespace;
+ var oHead = document.getElementsByTagName("head")[0];
+ for(var i = 0, len = namespace.length; i < len ; i++ )
+ {
+ if( namespace[i].used )
+ {
+ var newScript = document.createElement('script');
+ newScript.type = 'text/javascript';
+ newScript.src = format_url( namespace[i].path, sBaseUrl );
+ oHead.appendChild( newScript );
+ }
+ }
+}
+
+function write_insertion_included_scripts( sBaseUrl )
+{
+ var namespace = boostscript.namespace;
+ var sScriptsHtml = '';
+ for(var i = 0, len = namespace.length; i < len ; i++ )
+ {
+ if( namespace[i].used )
+ {
+ sScriptsHtml += '<script type="text/javascript" scr="' +
+ format_url( namespace[i].path, sBaseUrl ) +
+ '"></script>\n';
+ }
+ }
+ document.write( sScriptsHtml );
+}
+
+function format_base_url(sBaseUrl)
+{
+ return ( sBaseUrl != '' && sBaseUrl.charAt(sBaseUrl.length-1)!='/' ) ?
+ ( sBaseUrl + '/' ) : sBaseUrl;
+}
+
+function format_url(sUrl,sBaseUrl)
+{
+ return ( sUrl.substring(0,7) == 'http://' ) ? sUrl : ( sBaseUrl + sUrl );
+}
+
+function async_call( oNamespace, oFunc )
+{
+ if( ! oNamespace.loaded )
+ {
+ setTimeout( function() { async_call( oNamespace, oFunc ); }, 200 );
+ }
+ else
+ {
+ oFunc();
+ }
+}
+
+boostscript = new boostscript_library();
+boostscript.init = include_components;
+boostscript.async_call = async_call;
+boostscript.call = function(n,f,p1,p2,p3,p4,p5)
+{
+ async_call( n,
+ function()
+ {
+ n[f](p1,p2,p3,p4,p5);
+ }
+ );
+};
+
+})();
Added: sandbox/libpoet/trunk/doc/javascript/nested_links.js
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links.js 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,153 @@
+/*===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+===========================================================================*/
+
+/*********************** NestedLinks API **********************************
+
+In your html body use it like:
+----------------------------------------------------------------------------
+<!-- Include the grouped links java script api
+ Remember to change this line with the path of your nested_links.js -->
+
+<script type="text/javascript" src="nested_links.js"></script>
+
+<!-- Add a form with an "id" attribute -->
+
+<form id="boost_libs_list">
+
+ <!-- Call the NestedLinks "select box" with the following parameters
+ (1) id of the element where the select box will be inserted
+ (2) NestedLinks xml definition url
+ (3) user base url [optional]
+ (4) selected item [optional] -->
+
+ <script type="text/javascript">
+
+ nested_links_select_box('boost_libs_list',
+ 'boost_libs_grouped_links.xml');
+
+ </script>
+
+</form>
+---------------------------------------------------------------------------
+
+Read the html docs for more information.
+
+**************************************************************************/
+
+/* Requires: common.js */
+/* Requires: load_file.js */
+
+(function() {
+
+// Options for drop down list
+
+function construct_select_option(oXmlElement,sClass,
+ sBaseUrl,sDefaultUrl,sSelected)
+{
+ var sTag = oXmlElement.getAttribute('tag' );
+ var sUrl = oXmlElement.getAttribute('href');
+ return '<option ' +
+ ((sSelected == sTag) ? 'selected ' : '') +
+ 'class="' + sClass + '"' + ' value="' +
+ ( sUrl ? boostscript.common.format_url(sUrl,sBaseUrl) : sDefaultUrl ) +
+ '" >' + sTag + '</option>\n';
+}
+
+// Populate a select block from an xml and insert the result in sId div
+
+function select_box(sId,sXmlUrl,sUserBaseUrl,sSelected)
+{
+ boostscript.load_file.load_xml(sXmlUrl, function(oEntireXml) {
+
+ var oXml = oEntireXml.getElementsByTagName('nestedLinks')[0];
+
+ // manage parameters
+
+ var sBaseUrl = sUserBaseUrl ? boostscript.common.format_base_url( sUserBaseUrl ) : './';
+
+ var oBaseUrlNode = oXml.getElementsByTagName('base')[0];
+ if( oBaseUrlNode )
+ {
+ sBaseUrl += boost_format_base_url( oBaseUrlNode.getAttribute('href') );
+ }
+
+ var sDefaultUrl = sBaseUrl + 'index';
+ var oTitle = oXml.getElementsByTagName('title')[0];
+ if( sSelected == null && oTitle != null )
+ {
+ sSelected = oTitle.getAttribute('tag');
+ var sUrl = oTitle.getAttribute('href');
+ if( sUrl )
+ {
+ sDefaultUrl = sUrl;
+ }
+ }
+
+ // Construct the select box
+
+ var sSelectHtml =
+ '<select id="'+sId+'_internal"' +
+ ' class="nested-links"' +
+ ' size="1"' +
+ ' OnChange="' +
+ 'boostscript.nested_links.internal_go_to_url' +
+ '(\'' + sId + '_internal\')">\n' ;
+
+
+ sSelectHtml += construct_select_option(
+ oTitle, 'nested-links-title', sBaseUrl, sDefaultUrl, sSelected
+ );
+
+ var aGroups = oXml.childNodes;
+ for(var ig = 0, glen = aGroups.length; ig < glen; ig++)
+ {
+ var oGroup = aGroups[ig];
+ if( oGroup.nodeName == 'link' )
+ {
+ sSelectHtml += construct_select_option(
+ oGroup,
+ 'nested-links-first', sBaseUrl, sDefaultUrl, sSelected
+ );
+
+ var aItems = oGroup.childNodes;
+ for(var ii = 0, ilen = aItems.length; ii < ilen; ii++)
+ {
+ var oItem = aItems[ii];
+ if( oItem.nodeName == 'link' )
+ {
+ sSelectHtml += construct_select_option(
+ oItem,
+ 'nested-links-second', sBaseUrl, sDefaultUrl, sSelected
+ );
+ }
+ }
+ }
+ }
+
+ document.getElementById(sId).innerHTML = sSelectHtml + '</select>\n';
+
+ } );
+}
+
+// Action function used when the user selects an option from the drop down list
+
+function go_to_url(sId)
+{
+ var oe = document.getElementById(sId);
+ parent.self.location = oe.options[oe.selectedIndex].value;
+}
+
+// Public Interface
+
+boostscript.nested_links.internal_go_to_url = go_to_url;
+boostscript.nested_links.select_box = select_box;
+
+boostscript.nested_links.loaded = true;
+
+})();
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/css/grouped_links.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/css/grouped_links.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,53 @@
+/*=============================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+=============================================================================*/
+
+
+/******************************************************************************
+ Grouped Links
+******************************************************************************/
+
+ select.grouped_links
+ {
+ background-color: #BEDEBA;
+ font-weight: bold;
+ font-size: 12px;
+ color: #006D00;
+ border: 1px solid #DCDCDC;
+ border-bottom: 1px solid #9D9D9D;
+ border-right: 1px solid #9D9D9D;
+ padding-bottom: 1px;
+ padding-right: 1px;
+ }
+
+ option.grouped_links_title
+ {
+ background-color: #BEDEBA;
+ font-weight: bold;
+ font-size: 12px;
+ color: #006D00;
+ }
+
+ option.grouped_links_group
+ {
+ background-color: #008000;
+ font-weight: bold;
+ font-size: 12px;
+ color: white;
+ }
+
+ option.grouped_links_item
+ {
+ background-color: #FAFFFB;
+ padding: 0px 0px 0px 12px;
+ color: #006D00;
+ font-weight: normal;
+ }
+
+
+/*****************************************************************************/
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/doc/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/doc/jamfile.v2 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,26 @@
+# Boost.GroupedLinks
+#
+# Copyright (c) 2007 Matias Capeletto
+#
+# 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)
+
+
+import quickbook ;
+
+xml grouped_links
+ :
+ grouped_links.qbk
+ ;
+
+boostbook standalone
+ :
+ grouped_links
+ :
+ <xsl:param>toc.max.depth=2
+ <xsl:param>toc.section.depth=0
+ <xsl:param>chunk.section.depth=0
+ ;
+
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/doc/nested_links.qbk
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/doc/nested_links.qbk 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,229 @@
+[library Boost.GroupedLinks
+ [quickbook 1.4]
+ [authors [Capeletto, Matias]]
+ [copyright 2007 Matias Capeletto]
+ [category javascript]
+ [id grouped_links]
+ [dirname grouped_links]
+ [purpose
+ Construct a grouped links select box from a XML definition file
+ ]
+ [source-mode c++]
+ [license
+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])
+ ]
+]
+
+[/ QuickBook Document version 1.4 ]
+
+[def __GROUPED_LINKS_IMAGE__ [$images/grouped_links.png]]
+
+[section Introduction]
+
+GroupedLinks is a simple javascript API for building links select boxes.
+
+Features
+
+* Released under Boost Software License.
+* Cross-browser.
+* Items are populated from a simple XML definition file.
+* css based look & feel.
+* Support for relative URLs.
+* Integration with Boostbook.
+* Only standard javascript used.
+
+__GROUPED_LINKS_IMAGE__
+
+[endsect]
+
+[section Tutorial]
+
+
+[section GroupedLinks XML definition]
+
+A GroupedLinks select box is populated from a ['GroupedLinks XML definition]
+file. This is an important feature, because it means that the items are not
+harcoded in the HTML saving us space using global definitions and allowing
+us to change the definition with out touching the HTML files.
+
+['GroupedLinks XML definition] start with a tag named `groupedLinks`.
+There are only three elements:
+
+[table Elements
+[[Name][Purpose]]
+[[`title`][
+Add a title to the GroupedLinks select box. This is useful when
+you do not want to select any of the internals items. The select
+box will show the title instead.
+]]
+[[`group`][
+Starts a group list.
+]]
+[[`item`][
+Links items. They must reside inside a group list.
+]]
+]
+
+All the elements have two attributes:
+
+* [*tag: ] Name of the element, it will be showed in the HTML.
+* [*url: ] URL of the link. It can be relative or absolute. (It is optional)
+
+A ['GroupedLinks XML definition] will look like:
+
+``
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<groupedLinks version="1.0">
+
+<title tag="Title" url="group_1.html"/>
+
+<group tag="Group 1" url="group_1.html">
+
+ <item tag="Item A" url="group_1/item_A.html"/>
+ <item tag="Item B" url="group_1/item_A.html"/>
+ <item tag="Item C" url="http://www.item_C.com"/>
+
+</group>
+
+<group tag="Group 2" url="group_2.html">
+
+ <item tag="Item A" url="group_2/item_A.html"/>
+ <item tag="Item B" url="group_2/item_A.html"/>
+
+</group>
+
+<group tag="Group 3" url="group_3.html"/>
+
+</groupedLinks>
+``
+
+
+[endsect]
+
+[section Including a GroupedLinks select box in your HTML]
+
+To include a ['GroupedLinks select box] in the body of your HTML you have
+to create a form with an unique id and call the javascript function
+`grouped_links_select_box` inside of it.
+
+[table grouped_links_select_box function
+[[][Parameter Name][Purpose]]
+[[1][GroupedLinks XML URL][
+['GroupedLinks XML definition] URL.
+]]
+[[2][Form id][
+id of the form where you want to place the ['GroupedLinks select box].
+]]
+[[3][Base URL][
+A base URL that will be concatenated to all the relatives URLs.
+]]
+[[5][Selected item][
+The item that is selected by default. This parameter is optional, if
+you call the function with only three parameters the tag of the title
+element is used if there is one in the ['GroupedLinks XML definition].
+]]
+]
+
+It is simple enough to be understood from an example:
+
+``
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Boost.GroupedLinks Example</title>
+<link rel="stylesheet" href="../../css/grouped_links.css" type="text/css">
+</head>
+
+<body>
+
+<!-- /* Include the grouped links java script api */ -->
+
+<script type="text/javascript" src="../../js/grouped_links.js"></script>
+
+<!-- /* Add a form with an "id" attribute */ -->
+
+<form id="boost_libs_list">
+
+ <!--/* Call the GroupedLinks "select box" */-->
+
+ <script type="text/javascript">
+
+ grouped_links_select_box('boost_libs.xml',
+ 'boost_libs_list',
+ '../../',
+ 'Boost Libraries');
+
+ </script>
+
+</form>
+``
+
+[note
+Remember to change the `src` of the javascript include line to point
+to the URL of `grouped_links.js` in your system. Try to work with
+relatives paths so the HTML can be easily moved.
+]
+
+[endsect]
+
+[section Boostbook integration]
+
+Add the following lines to your jamfile.v2
+
+ <xsl:param>grouped.links.chapters.show="'true'"
+ <xsl:param>grouped.links.sections.show="'true'"
+ <xsl:param>grouped.links.sections.xml="'sections.XML'" # your XML sections
+
+GroupedLinks select boxes for boost libraries and internal sections can be
+requested to boostbook using the following options:
+
+[table Boostbook GroupedLinks Parameters
+[[Name][Purpose]]
+[[`show`][Include select box]]
+[[`xml`][Path to the XML definition]]
+[[`url`][Base URL to use with relative paths]]
+]
+
+You can configure all the parameters used by boostbook:
+
+ <xsl:param>grouped.links.js="'grouped_links.js'"
+
+ <xsl:param>grouped.links.chapters.show="'true'"
+ <xsl:param>grouped.links.chapters.xml="'boost_libs_grouped_links.XML'"
+ <xsl:param>grouped.links.chapters.url="''"
+
+ <xsl:param>grouped.links.sections.show="'true'"
+ <xsl:param>grouped.links.sections.xml="'sections_grouped_links.XML'"
+ <xsl:param>grouped.links.sections.url="''"
+
+[endsect]
+
+[endsect]
+
+[section Examples]
+
+In the folder `example` you can find two examples using GropedLinks API.
+
+[variablelist
+[[simple][
+How to put a GropedLinks select box in your HTML body.
+]]
+[[boostbook][
+How to integrate GroupedLinks with boostbook and quickbook docs.
+]]
+]
+
+[endsect]
+
+[section Acknowledgments]
+
+Thanks Martin Capeletto (my brother) for teaching me the basics of javascript.
+
+Thanks to the ones that participates in constructing the new boost docs
+look & feel. Special thanks to John Maddock for his support during this period.
+
+[endsect]
+
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/HTML.manifest
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/HTML.manifest 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1 @@
+index.html
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/images/grouped_links.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/index.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/doc/xhtml/index.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,670 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Chapter 1. Boost.GroupedLinks</title>
+ <link xmlns="" rel="stylesheet" href="boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.70.1" />
+ <link rel="start" href="index.html" title="Chapter 1. Boost.GroupedLinks" />
+ </head>
+ <body>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box"></div>
+ <div class="heading_search_box"></div>
+ </div>
+ <div class="spirit-nav"></div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="chapter" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title"><a id="grouped_links"></a>Chapter 1. Boost.GroupedLinks</h2>
+ </div>
+ <div>
+ <div class="author">
+ <h3 class="author"><span class="firstname">Matias</span> <span class="surname">Capeletto</span></h3>
+ </div>
+ </div>
+ <div>
+ <p class="copyright">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div>
+ <div class="legalnotice">
+ <a id="id2601623"></a>
+ <p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a xmlns="" href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt>)
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="toc">
+ <p>
+ <b>Table of Contents</b>
+ </p>
+ <dl>
+ <dt>
+ <span class="section">
+ Introduction
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Tutorial
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Examples
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Acknowledgments
+ </span>
+ </dt>
+ </dl>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="grouped_links.introduction"></a>
+ Introduction
+ </h2>
+ </div>
+ </div>
+ </div>
+ <p>
+ GroupedLinks is a simple javascript API for building links select boxes.
+ </p>
+ <p>
+ Features
+ </p>
+ <div class="itemizedlist">
+ <ul type="disc">
+ <li>
+ Released under Boost Software License.
+ </li>
+ <li>
+ Cross-browser.
+ </li>
+ <li>
+ Items are populated from a simple XML definition file.
+ </li>
+ <li>
+ css based look & feel.
+ </li>
+ <li>
+ Support for relative URLs.
+ </li>
+ <li>
+ Integration with Boostbook.
+ </li>
+ <li>
+ Only standard javascript used.
+ </li>
+ </ul>
+ </div>
+ <p>
+ <span class="inlinemediaobject"><img src="images/grouped_links.png" alt="grouped_links" /></span>
+ </p>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="grouped_links.tutorial"></a>
+ Tutorial
+ </h2>
+ </div>
+ </div>
+ </div>
+ <div class="toc">
+ <dl>
+ <dt>
+ <span class="section">
+ <a href="index.html#grouped_links.tutorial.groupedlinks_xml_definition">GroupedLinks
+ XML definition</a>
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ <a href="index.html#grouped_links.tutorial.including_a_groupedlinks_select_box_in_your_html">Including
+ a GroupedLinks select box in your HTML</a>
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ <a href="index.html#grouped_links.tutorial.boostbook_integration">Boostbook
+ integration</a>
+ </span>
+ </dt>
+ </dl>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="grouped_links.tutorial.groupedlinks_xml_definition"></a>
+ <a href="index.html#grouped_links.tutorial.groupedlinks_xml_definition" title="GroupedLinks XML definition">GroupedLinks
+ XML definition</a>
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ A GroupedLinks select box is populated from a <span class="emphasis"><em>GroupedLinks XML
+ definition</em></span> file. This is an important feature, because it means
+ that the items are not harcoded in the HTML saving us space using global
+ definitions and allowing us to change the definition with out touching the
+ HTML files.
+ </p>
+ <p>
+ <span class="emphasis"><em>GroupedLinks XML definition</em></span> start with a tag named
+ <code class="computeroutput"><span class="identifier">groupedLinks</span></code>. There are only
+ three elements:
+ </p>
+ <div class="table">
+ <a id="id2565416"></a>
+ <p class="title">
+ <b>Table 1.1. Elements</b>
+ </p>
+ <div class="table-contents">
+ <table xmlns="" class="table" summary="Elements">
+ <colgroup>
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ </colgroup>
+ <thead xmlns="http://www.w3.org/1999/xhtml">
+ <tr>
+ <th>
+ <p>
+ Name
+ </p>
+ </th>
+ <th>
+ <p>
+ Purpose
+ </p>
+ </th>
+ </tr>
+ </thead>
+ <tbody xmlns="http://www.w3.org/1999/xhtml">
+ <tr>
+ <td>
+ <p>
+ <code class="computeroutput"><span class="identifier">title</span></code>
+ </p>
+ </td>
+ <td>
+ <p>
+ Add a title to the GroupedLinks select box. This is useful when you
+ do not want to select any of the internals items. The select box will
+ show the title instead.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ <code class="computeroutput"><span class="identifier">group</span></code>
+ </p>
+ </td>
+ <td>
+ <p>
+ Starts a group list.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ <code class="computeroutput"><span class="identifier">item</span></code>
+ </p>
+ </td>
+ <td>
+ <p>
+ Links items. They must reside inside a group list.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <br class="table-break" />
+ <p>
+ All the elements have two attributes:
+ </p>
+ <div class="itemizedlist">
+ <ul type="disc">
+ <li><span class="bold"><strong>tag: </strong></span> Name of the element, it will be
+ showed in the HTML.
+ </li>
+ <li><span class="bold"><strong>url: </strong></span> URL of the link. It can be relative
+ or absolute. (It is optional)
+ </li>
+ </ul>
+ </div>
+ <p>
+ A <span class="emphasis"><em>GroupedLinks XML definition</em></span> will look like:
+ </p>
+ <p>
+
+</p>
+ <pre class="programlisting">
+<span class="special"><?</span><span class="identifier">xml</span> <span class="identifier">version</span><span class="special">=</span><span class="string">"1.0"</span> <span class="identifier">encoding</span><span class="special">=</span><span class="string">"UTF-8"</span> <span class="special">?></span>
+
+<span class="special"><</span><span class="identifier">groupedLinks</span> <span class="identifier">version</span><span class="special">=</span><span class="string">"1.0"</span><span class="special">></span>
+
+<span class="special"><</span><span class="identifier">title</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Title"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_1.html"</span><span class="special">/></span>
+
+<span class="special"><</span><span class="identifier">group</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Group 1"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_1.html"</span><span class="special">></span>
+
+ <span class="special"><</span><span class="identifier">item</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Item A"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_1/item_A.html"</span><span class="special">/></span>
+ <span class="special"><</span><span class="identifier">item</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Item B"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_1/item_A.html"</span><span class="special">/></span>
+ <span class="special"><</span><span class="identifier">item</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Item C"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"http://www.item_C.com"</span><span class="special">/></span>
+
+<span class="special"></</span><span class="identifier">group</span><span class="special">></span>
+
+<span class="special"><</span><span class="identifier">group</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Group 2"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_2.html"</span><span class="special">></span>
+
+ <span class="special"><</span><span class="identifier">item</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Item A"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_2/item_A.html"</span><span class="special">/></span>
+ <span class="special"><</span><span class="identifier">item</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Item B"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_2/item_A.html"</span><span class="special">/></span>
+
+<span class="special"></</span><span class="identifier">group</span><span class="special">></span>
+
+<span class="special"><</span><span class="identifier">group</span> <span class="identifier">tag</span><span class="special">=</span><span class="string">"Group 3"</span> <span class="identifier">url</span><span class="special">=</span><span class="string">"group_3.html"</span><span class="special">/></span>
+
+<span class="special"></</span><span class="identifier">groupedLinks</span><span class="special">></span>
+</pre>
+ <p>
+ </p>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="grouped_links.tutorial.including_a_groupedlinks_select_box_in_your_html"></a>
+ <a href="index.html#grouped_links.tutorial.including_a_groupedlinks_select_box_in_your_html" title="Including a GroupedLinks select box in your HTML">Including
+ a GroupedLinks select box in your HTML</a>
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ To include a <span class="emphasis"><em>GroupedLinks select box</em></span> in the body of
+ your HTML you have to create a form with an unique id and call the javascript
+ function <code class="computeroutput"><span class="identifier">grouped_links_select_box</span></code>
+ inside of it.
+ </p>
+ <div class="table">
+ <a id="id2611051"></a>
+ <p class="title">
+ <b>Table 1.2. grouped_links_select_box function</b>
+ </p>
+ <div class="table-contents">
+ <table xmlns="" class="table" summary="grouped_links_select_box function">
+ <colgroup>
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ </colgroup>
+ <thead xmlns="http://www.w3.org/1999/xhtml">
+ <tr>
+ <th>
+ <p>
+ </p>
+ </th>
+ <th>
+ <p>
+ Parameter Name
+ </p>
+ </th>
+ <th>
+ <p>
+ Purpose
+ </p>
+ </th>
+ </tr>
+ </thead>
+ <tbody xmlns="http://www.w3.org/1999/xhtml">
+ <tr>
+ <td>
+ <p>
+ 1
+ </p>
+ </td>
+ <td>
+ <p>
+ GroupedLinks XML URL
+ </p>
+ </td>
+ <td>
+ <p>
+ <span class="emphasis"><em>GroupedLinks XML definition</em></span> URL.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ 2
+ </p>
+ </td>
+ <td>
+ <p>
+ Form id
+ </p>
+ </td>
+ <td>
+ <p>
+ id of the form where you want to place the <span class="emphasis"><em>GroupedLinks select
+ box</em></span>.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ 3
+ </p>
+ </td>
+ <td>
+ <p>
+ Base URL
+ </p>
+ </td>
+ <td>
+ <p>
+ A base URL that will be concatenated to all the relatives URLs.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ 5
+ </p>
+ </td>
+ <td>
+ <p>
+ Selected item
+ </p>
+ </td>
+ <td>
+ <p>
+ The item that is selected by default. This parameter is optional, if
+ you call the function with only three parameters the tag of the title
+ element is used if there is one in the <span class="emphasis"><em>GroupedLinks XML definition</em></span>.
+ </p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <br class="table-break" />
+ <p>
+ It is simple enough to be understood from an example:
+ </p>
+ <p>
+
+</p>
+ <pre class="programlisting">
+<span class="special"><</span><span class="identifier">head</span><span class="special">></span>
+<span class="special"><</span><span class="identifier">meta</span> <span class="identifier">http</span><span class="special">-</span><span class="identifier">equiv</span><span class="special">=</span><span class="string">"Content-Type"</span> <span class="identifier">content</span><span class="special">=</span><span class="string">"text/html; charset=ISO-8859-1"</span><span class="special">></span>
+<span class="special"><</span><span class="identifier">title</span><span class="special">></span><span class="identifier">Boost</span><span class="special">.</span><span class="identifier">GroupedLinks</span> <span class="identifier">Example</span><span class="special"></</span><span class="identifier">title</span><span class="special">></span>
+<span class="special"><</span><span class="identifier">link</span> <span class="identifier">rel</span><span class="special">=</span><span class="string">"stylesheet"</span> <span class="identifier">href</span><span class="special">=</span><span class="string">"../../css/grouped_links.css"</span> <span class="identifier">type</span><span class="special">=</span><span class="string">"text/css"</span><span class="special">></span>
+<span class="special"></</span><span class="identifier">head</span><span class="special">></span>
+
+<span class="special"><</span><span class="identifier">body</span><span class="special">></span>
+
+<span class="special"><!--</span> <span class="comment">/* Include the grouped links java script api */</span> <span class="special">--></span>
+
+<span class="special"><</span><span class="identifier">script</span> <span class="identifier">type</span><span class="special">=</span><span class="string">"text/javascript"</span> <span class="identifier">src</span><span class="special">=</span><span class="string">"../../js/grouped_links.js"</span><span class="special">></</span><span class="identifier">script</span><span class="special">></span>
+
+<span class="special"><!--</span> <span class="comment">/* Add a form with an "id" attribute */</span> <span class="special">--></span>
+
+<span class="special"><</span><span class="identifier">form</span> <span class="identifier">id</span><span class="special">=</span><span class="string">"boost_libs_list"</span><span class="special">></span>
+
+ <span class="special"><!--/*</span> <span class="identifier">Call</span> <span class="identifier">the</span> <span class="identifier">GroupedLinks</span> <span class="string">"select box"</span> <span class="special">*/--></span>
+
+ <span class="special"><</span><span class="identifier">script</span> <span class="identifier">type</span><span class="special">=</span><span class="string">"text/javascript"</span><span class="special">></span>
+
+ <span class="identifier">grouped_links_select_box</span><span class="special">(</span><span class="char">'boost_libs.xml'</span><span class="special">,</span>
+ <span class="char">'boost_libs_list'</span><span class="special">,</span>
+ <span class="char">'../../'</span><span class="special">,</span>
+ <span class="char">'Boost Libraries'</span><span class="special">);</span>
+
+ <span class="special"></</span><span class="identifier">script</span><span class="special">></span>
+
+<span class="special"></</span><span class="identifier">form</span><span class="special">></span>
+</pre>
+ <p>
+ </p>
+ <div xmlns="" class="note">
+ <div class="admonition-graphic">
+ <img alt="[Note]" src="../../doc/html/images/note.png" />
+ </div>
+ <div class="admonition-body">
+ <div class="admonition-title">Note</div>
+ <div class="admonition-content">
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ </p>
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ Remember to change the <code class="computeroutput"><span class="identifier">src</span></code>
+ of the javascript include line to point to the URL of <code class="computeroutput"><span class="identifier">grouped_links</span><span class="special">.</span><span class="identifier">js</span></code>
+ in your system. Try to work with relatives paths so the HTML can be easily
+ moved.
+ </p>
+ <p xmlns="http://www.w3.org/1999/xhtml">
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="grouped_links.tutorial.boostbook_integration"></a>
+ <a href="index.html#grouped_links.tutorial.boostbook_integration" title="Boostbook integration">Boostbook
+ integration</a>
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ Add the following lines to your jamfile.v2
+ </p>
+ <pre class="programlisting">
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">chapters</span><span class="special">.</span><span class="identifier">show</span><span class="special">=</span><span class="string">"'true'"</span>
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">sections</span><span class="special">.</span><span class="identifier">show</span><span class="special">=</span><span class="string">"'true'"</span>
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">sections</span><span class="special">.</span><span class="identifier">xml</span><span class="special">=</span><span class="string">"'sections.XML'"</span> <span class="preprocessor"># your</span> <span class="identifier">XML</span> <span class="identifier">sections</span>
+</pre>
+ <p>
+ GroupedLinks select boxes for boost libraries and internal sections can be
+ requested to boostbook using the following options:
+ </p>
+ <div class="table">
+ <a id="id2611978"></a>
+ <p class="title">
+ <b>Table 1.3. Boostbook GroupedLinks Parameters</b>
+ </p>
+ <div class="table-contents">
+ <table xmlns="" class="table" summary="Boostbook GroupedLinks Parameters">
+ <colgroup>
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ <col xmlns="http://www.w3.org/1999/xhtml" />
+ </colgroup>
+ <thead xmlns="http://www.w3.org/1999/xhtml">
+ <tr>
+ <th>
+ <p>
+ Name
+ </p>
+ </th>
+ <th>
+ <p>
+ Purpose
+ </p>
+ </th>
+ </tr>
+ </thead>
+ <tbody xmlns="http://www.w3.org/1999/xhtml">
+ <tr>
+ <td>
+ <p>
+ <code class="computeroutput"><span class="identifier">show</span></code>
+ </p>
+ </td>
+ <td>
+ <p>
+ Include select box
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ <code class="computeroutput"><span class="identifier">xml</span></code>
+ </p>
+ </td>
+ <td>
+ <p>
+ Path to the XML definition
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>
+ <p>
+ <code class="computeroutput"><span class="identifier">url</span></code>
+ </p>
+ </td>
+ <td>
+ <p>
+ Base URL to use with relative paths
+ </p>
+ </td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <br class="table-break" />
+ <p>
+ You can configure all the parameters used by boostbook:
+ </p>
+ <pre class="programlisting">
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">js</span><span class="special">=</span><span class="string">"'grouped_links.js'"</span>
+
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">chapters</span><span class="special">.</span><span class="identifier">show</span><span class="special">=</span><span class="string">"'true'"</span>
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">chapters</span><span class="special">.</span><span class="identifier">xml</span><span class="special">=</span><span class="string">"'boost_libs_grouped_links.XML'"</span>
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">chapters</span><span class="special">.</span><span class="identifier">url</span><span class="special">=</span><span class="string">"''"</span>
+
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">sections</span><span class="special">.</span><span class="identifier">show</span><span class="special">=</span><span class="string">"'true'"</span>
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">sections</span><span class="special">.</span><span class="identifier">xml</span><span class="special">=</span><span class="string">"'sections_grouped_links.XML'"</span>
+<span class="special"><</span><span class="identifier">xsl</span><span class="special">:</span><span class="identifier">param</span><span class="special">></span><span class="identifier">grouped</span><span class="special">.</span><span class="identifier">links</span><span class="special">.</span><span class="identifier">sections</span><span class="special">.</span><span class="identifier">url</span><span class="special">=</span><span class="string">"''"</span>
+</pre>
+ </div>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="grouped_links.examples"></a>
+ Examples
+ </h2>
+ </div>
+ </div>
+ </div>
+ <p>
+ In the folder <code class="computeroutput"><span class="identifier">example</span></code> you can
+ find two examples using GropedLinks API.
+ </p>
+ <div class="variablelist">
+ <p class="title">
+ <b></b>
+ </p>
+ <dl>
+ <dt>
+ <span class="term">simple</span>
+ </dt>
+ <dd>
+ How to put a GropedLinks select box in your HTML body.
+ </dd>
+ <dt>
+ <span class="term">boostbook</span>
+ </dt>
+ <dd>
+ How to integrate GroupedLinks with boostbook and quickbook docs.
+ </dd>
+ </dl>
+ </div>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="grouped_links.acknowledgments"></a>
+ Acknowledgments
+ </h2>
+ </div>
+ </div>
+ </div>
+ <p>
+ Thanks Martin Capeletto (my brother) for teaching me the basics of javascript.
+ </p>
+ <p>
+ Thanks to the ones that participates in constructing the new boost docs look
+ & feel. Special thanks to John Maddock for his support during this period.
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav"></div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="revised">Revised: June 13, 2007 at 00:31:24 GMT</div>
+ <div id="copyright"></div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/example.qbk
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/example.qbk 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,76 @@
+[library Boost.GroupedLinks example
+ [quickbook 1.4]
+ [authors [Capeletto, Matias]]
+ [copyright 2007 Matias Capeletto]
+ [category example]
+ [id boostbook_integration]
+ [dirname boostbook_integration]
+ [purpose
+ Boost.GroupedLinks Boostbook Integration example
+ ]
+ [source-mode c++]
+ [license
+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])
+ ]
+]
+
+[/ QuickBook Document version 1.4 ]
+
+
+[section Preface]
+Preface section
+[endsect]
+
+[section First]
+First section
+
+[section Sub A]
+First section - subsection A
+
+
+[endsect]
+
+[section Sub B]
+First section - subsection B
+
+
+[endsect]
+
+[section Sub C]
+First section - subsection C
+
+
+[endsect]
+
+[endsect]
+
+[section Second]
+Second section
+
+[section Sub A]
+Second section - subsection A
+
+
+[endsect]
+
+[section Sub B]
+Second section - subsection B
+
+
+[endsect]
+
+[endsect]
+
+[section Final]
+Final section
+
+
+[endsect]
+
+
+
+
+
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/jamfile.v2
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/jamfile.v2 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,31 @@
+# Boost.GroupedLinks
+#
+# Copyright (c) 2007 Matias Capeletto
+#
+# 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)
+
+
+# Quickbook
+# -----------------------------------------------------------------------------
+
+import quickbook ;
+
+xml example
+ :
+ example.qbk
+ ;
+
+boostbook standalone
+ :
+ example
+ :
+ # Show the sections select box, the chapters select box is showed by default
+ <xsl:param>grouped.links.sections.show="'true'"
+
+ <xsl:param>toc.max.depth=2
+ <xsl:param>toc.section.depth=4
+ <xsl:param>chunk.section.depth=3
+ ;
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/HTML.manifest
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/HTML.manifest 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,7 @@
+index.html
+boostbook_integration/first.html
+boostbook_integration/first/sub_b.html
+boostbook_integration/first/sub_c.html
+boostbook_integration/second.html
+boostbook_integration/second/sub_b.html
+boostbook_integration/final.html
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/final.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/final.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,116 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Final</title>
+ <link xmlns="" rel="stylesheet" href="../boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="up" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="prev" href="second/sub_b.html" title="Sub B" />
+ </head>
+ <body>
+ <script type="text/javascript" src="../grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../sections_grouped_links.xml',
+ 'sections_select_box',
+ '.././');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="second/sub_b.html">
+ <img src="../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../index.html">
+ <img src="../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../index.html">
+ <img src="../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="boostbook_integration.final"></a>
+ Final
+ </h2>
+ </div>
+ </div>
+ </div>
+ <p>
+ Final section
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="second/sub_b.html">
+ <img src="../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../index.html">
+ <img src="../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../index.html">
+ <img src="../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="copyright">
+ <p xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,167 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>First</title>
+ <link xmlns="" rel="stylesheet" href="../boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="up" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="prev" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="next" href="first/sub_b.html" title="Sub B" />
+ </head>
+ <body>
+ <script type="text/javascript" src="../grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../sections_grouped_links.xml',
+ 'sections_select_box',
+ '.././');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="../index.html">
+ <img src="../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../index.html">
+ <img src="../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../index.html">
+ <img src="../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="first/sub_b.html">
+ <img src="../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="boostbook_integration.first"></a>
+ First
+ </h2>
+ </div>
+ </div>
+ </div>
+ <div xmlns="" class="toc">
+ <div class="box-outer-wrapper">
+ <div class="box-top-left"></div>
+ <div class="box-top-right"></div>
+ <div class="box-top"></div>
+ <div class="box-inner-wrapper">
+ <dl xmlns="http://www.w3.org/1999/xhtml">
+ <dt>
+ <span class="section">
+ Sub A
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Sub B
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Sub C
+ </span>
+ </dt>
+ </dl>
+ </div>
+ <div class="box-bottom-left"></div>
+ <div class="box-bottom-right"></div>
+ <div class="box-bottom"></div>
+ </div>
+ </div>
+ <p>
+ First section
+ </p>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="boostbook_integration.first.sub_a"></a>
+ Sub A
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ First section - subsection A
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="../index.html">
+ <img src="../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../index.html">
+ <img src="../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../index.html">
+ <img src="../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="first/sub_b.html">
+ <img src="../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="copyright">
+ <p xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/sub_b.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/sub_b.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Sub B</title>
+ <link xmlns="" rel="stylesheet" href="../../boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="../../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="up" href="../first.html" title="First" />
+ <link rel="prev" href="../first.html" title="First" />
+ <link rel="next" href="sub_c.html" title="Sub C" />
+ </head>
+ <body>
+ <script type="text/javascript" src="../../grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../../boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../../sections_grouped_links.xml',
+ 'sections_select_box',
+ '../.././');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="../first.html">
+ <img src="../../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../first.html">
+ <img src="../../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../../index.html">
+ <img src="../../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="sub_c.html">
+ <img src="../../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="boostbook_integration.first.sub_b"></a>
+ Sub B
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ First section - subsection B
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="../first.html">
+ <img src="../../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../first.html">
+ <img src="../../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../../index.html">
+ <img src="../../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="sub_c.html">
+ <img src="../../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="copyright">
+ <p xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/sub_c.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/first/sub_c.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Sub C</title>
+ <link xmlns="" rel="stylesheet" href="../../boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="../../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="up" href="../first.html" title="First" />
+ <link rel="prev" href="sub_b.html" title="Sub B" />
+ <link rel="next" href="../second.html" title="Second" />
+ </head>
+ <body>
+ <script type="text/javascript" src="../../grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../../boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../../sections_grouped_links.xml',
+ 'sections_select_box',
+ '../.././');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="sub_b.html">
+ <img src="../../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../first.html">
+ <img src="../../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../../index.html">
+ <img src="../../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="../second.html">
+ <img src="../../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="boostbook_integration.first.sub_c"></a>
+ Sub C
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ First section - subsection C
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="sub_b.html">
+ <img src="../../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../first.html">
+ <img src="../../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../../index.html">
+ <img src="../../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="../second.html">
+ <img src="../../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="copyright">
+ <p xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Second</title>
+ <link xmlns="" rel="stylesheet" href="../boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="up" href="../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="prev" href="first/sub_c.html" title="Sub C" />
+ <link rel="next" href="second/sub_b.html" title="Sub B" />
+ </head>
+ <body>
+ <script type="text/javascript" src="../grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../sections_grouped_links.xml',
+ 'sections_select_box',
+ '.././');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="first/sub_c.html">
+ <img src="../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../index.html">
+ <img src="../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../index.html">
+ <img src="../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="second/sub_b.html">
+ <img src="../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="boostbook_integration.second"></a>
+ Second
+ </h2>
+ </div>
+ </div>
+ </div>
+ <div xmlns="" class="toc">
+ <div class="box-outer-wrapper">
+ <div class="box-top-left"></div>
+ <div class="box-top-right"></div>
+ <div class="box-top"></div>
+ <div class="box-inner-wrapper">
+ <dl xmlns="http://www.w3.org/1999/xhtml">
+ <dt>
+ <span class="section">
+ Sub A
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Sub B
+ </span>
+ </dt>
+ </dl>
+ </div>
+ <div class="box-bottom-left"></div>
+ <div class="box-bottom-right"></div>
+ <div class="box-bottom"></div>
+ </div>
+ </div>
+ <p>
+ Second section
+ </p>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="boostbook_integration.second.sub_a"></a>
+ Sub A
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ Second section - subsection A
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="first/sub_c.html">
+ <img src="../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../index.html">
+ <img src="../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../index.html">
+ <img src="../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="second/sub_b.html">
+ <img src="../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="copyright">
+ <p xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second/sub_b.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/boostbook_integration/second/sub_b.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,123 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Sub B</title>
+ <link xmlns="" rel="stylesheet" href="../../boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="../../index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="up" href="../second.html" title="Second" />
+ <link rel="prev" href="../second.html" title="Second" />
+ <link rel="next" href="../final.html" title="Final" />
+ </head>
+ <body>
+ <script type="text/javascript" src="../../grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../../boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ '../../sections_grouped_links.xml',
+ 'sections_select_box',
+ '../.././');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="../second.html">
+ <img src="../../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../second.html">
+ <img src="../../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../../index.html">
+ <img src="../../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="../final.html">
+ <img src="../../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h3 class="title">
+ <a id="boostbook_integration.second.sub_b"></a>
+ Sub B
+ </h3>
+ </div>
+ </div>
+ </div>
+ <p>
+ Second section - subsection B
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="p" href="../second.html">
+ <img src="../../../../doc/html/images/prev.png" alt="Prev" />
+ </a>
+ <a accesskey="u" href="../second.html">
+ <img src="../../../../doc/html/images/up.png" alt="Up" />
+ </a>
+ <a accesskey="h" href="../../index.html">
+ <img src="../../../../doc/html/images/home.png" alt="Home" />
+ </a>
+ <a accesskey="n" href="../final.html">
+ <img src="../../../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="copyright">
+ <p xmlns:rev="http://www.cs.rpi.edu/~gregod/boost/tools/doc/revision">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/build_grouped_links.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/build_grouped_links.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,63 @@
+#include <iostream>
+#include <fstream>
+#include <string>
+#include <functional>
+#include <algorithm>
+
+#include <boost/property_tree/ptree.hpp>
+#include <boost/property_tree/xml_parser.hpp>
+#include <boost/optional.hpp>
+#include <boost/none.hpp>
+
+using namespace boost::property_tree;
+using namespace boost;
+using namespace std;
+
+
+optional<ptree&> find_toc( ptree& html )
+{
+ ptree& pbody = html.get_child("html.body");
+ for( ptree::iterator i = pbody.begin(), ie = pbody.end();
+ i != ie ; ++i )
+ {
+ std::cout << i->second.get<string>("<xmlattr>","") << std::endl;
+ if( i->second.get<string>("<xmlattr>","") == "body" )
+ {
+ ptree& pc = i->second.get_child("div.div.div");
+ for( ptree::iterator ic = pc.begin(), iec = pc.end();
+ ic != iec ; ++ic )
+ {
+ if( i->second.get<string>("<xmlattr>","") == "toc" )
+ {
+ return i->second.get_child("dl");
+ }
+ }
+ }
+ }
+ return none;
+}
+
+int main()
+{
+ ptree html;
+
+ std::string in_name = "index.html";
+/*
+ ifstream inhtml( in_name.c_str(), ios_base::in );
+ if( !inhtml )
+ {
+ std::cout << std::endl << "dow!" << std::endl;
+ }
+*/
+ read_xml(in_name,html);
+
+ optional<ptree&> toc = find_toc(html);
+ if( toc )
+ {
+ std::cout << std::endl << "great!" << std::endl;
+ }
+
+
+ return 0;
+}
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/index.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/index.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+ <head xmlns="http://www.w3.org/1999/xhtml">
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
+ <title>Chapter 1. Boost.GroupedLinks example</title>
+ <link xmlns="" rel="stylesheet" href="boostbook.css" type="text/css" />
+ <meta name="generator" content="DocBook XSL Stylesheets V1.72.0" />
+ <link rel="start" href="index.html" title="Chapter 1. Boost.GroupedLinks example" />
+ <link rel="next" href="boostbook_integration/first.html" title="First" />
+ </head>
+ <body>
+ <script type="text/javascript" src="grouped_links.js"></script>
+ <div id="heading">
+ <div id="heading-placard"></div>
+ <div class="heading_navigation_box">
+ <div class="grouped_links" id="chapters_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ 'boost_libs_grouped_links.xml',
+ 'chapters_select_box',
+ 'http://www.boost.org/libs/');
+ </script>
+ </div>
+ <div class="grouped_links" id="sections_select_box">
+ <script type="text/javascript">
+ grouped_links_select_box(
+ 'sections_grouped_links.xml',
+ 'sections_select_box',
+ './');
+ </script>
+ </div>
+ </div>
+ <div class="heading_search_box">
+ <form id="cref" action="http://google.com/cse">
+ <input type="hidden" name="cref" value="" />
+ <div> Search Boost </div>
+ <div>
+ <input class="search_box" type="text" name="q" id="q" size="40" maxlength="255" alt="Search Text" />
+ </div>
+ </form>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="n" href="boostbook_integration/first.html">
+ <img src="../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="body">
+ <div id="body-inner">
+ <div id="content">
+ <div xmlns="http://www.w3.org/1999/xhtml" class="chapter" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title"><a id="boostbook_integration"></a>Chapter 1. Boost.GroupedLinks example</h2>
+ </div>
+ <div>
+ <div class="author">
+ <h3 class="author"><span class="firstname">Matias</span> <span class="surname">Capeletto</span></h3>
+ </div>
+ </div>
+ <div>
+ <p class="copyright">Copyright © 2007 Matias Capeletto</p>
+ </div>
+ <div>
+ <div class="legalnotice">
+ <a id="id2597309"></a>
+ <p>
+ Distributed under the Boost Software License, Version 1.0. (See accompanying
+ file LICENSE_1_0.txt or copy at <a xmlns="" href="http://www.boost.org/LICENSE_1_0.txt" target="_top">http://www.boost.org/LICENSE_1_0.txt>)
+ </p>
+ </div>
+ </div>
+ </div>
+ </div>
+ <div xmlns="" class="toc">
+ <div class="box-outer-wrapper">
+ <div class="box-top-left"></div>
+ <div class="box-top-right"></div>
+ <div class="box-top"></div>
+ <div class="box-inner-wrapper">
+ <p>
+ <b>Table of Contents</b>
+ </p>
+ <dl xmlns="http://www.w3.org/1999/xhtml">
+ <dt>
+ <span class="section">
+ Preface
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ First
+ </span>
+ </dt>
+ <dd>
+ <dl>
+ <dt>
+ <span class="section">
+ Sub A
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Sub B
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Sub C
+ </span>
+ </dt>
+ </dl>
+ </dd>
+ <dt>
+ <span class="section">
+ Second
+ </span>
+ </dt>
+ <dd>
+ <dl>
+ <dt>
+ <span class="section">
+ Sub A
+ </span>
+ </dt>
+ <dt>
+ <span class="section">
+ Sub B
+ </span>
+ </dt>
+ </dl>
+ </dd>
+ <dt>
+ <span class="section">
+ Final
+ </span>
+ </dt>
+ </dl>
+ </div>
+ <div class="box-bottom-left"></div>
+ <div class="box-bottom-right"></div>
+ <div class="box-bottom"></div>
+ </div>
+ </div>
+ <div class="section" lang="en" xml:lang="en">
+ <div class="titlepage">
+ <div>
+ <div>
+ <h2 class="title" style="clear: both">
+ <a id="boostbook_integration.preface"></a>
+ Preface
+ </h2>
+ </div>
+ </div>
+ </div>
+ <p>
+ Preface section
+ </p>
+ </div>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </div>
+ <div class="spirit-nav">
+ <a accesskey="n" href="boostbook_integration/first.html">
+ <img src="../../doc/html/images/next.png" alt="Next" />
+ </a>
+ </div>
+ <div id="footer">
+ <div id="footer-left">
+ <div id="revised">Revised: June 15, 2007 at 15:06:18 GMT</div>
+ <div id="copyright"></div>
+ <div id="license">
+ <p>Distributed under the
+ Boost Software License, Version 1.0.
+ </p>
+ </div>
+ </div>
+ <div id="footer-right">
+ <div id="banners">
+ <p id="banner-xhtml">
+ XHTML 1.0
+ </p>
+ <p id="banner-css">
+ CSS
+ </p>
+ <p id="banner-sourceforge">
+ SourceForge
+ </p>
+ </div>
+ </div>
+ <div class="clear"></div>
+ </div>
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/sections.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/boostbook_integration/xhtml/sections.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--=========================================================================
+
+ Grouped links for Boost.GroupedLinks boostbook integration example
+
+ Copyright (c) 2007 Matias Capeletto
+
+ 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)
+
+===========================================================================-->
+
+
+<groupedLinks version="1.0">
+
+<title tag="Sections" url="index.html"/>
+
+<group tag="Preface" url="index.html"/>
+
+<group tag="First" url="boostbook_integration/first.html">
+ <item tag="Sub A" url="boostbook_integration/first.html"/>
+ <item tag="Sub B" url="boostbook_integration/first/sub_b.html"/>
+ <item tag="Sub C" url="boostbook_integration/first/sub_c.html"/>
+</group>
+
+<group tag="Second" url="boostbook_integration/second.html">
+ <item tag="Sub A" url="boostbook_integration/second.html"/>
+ <item tag="Sub B" url="boostbook_integration/second/sub_b.html"/>
+</group>
+
+<group tag="Final" url="boostbook_integration/final.html"/>
+
+</groupedLinks>
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/boost_libs.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/boost_libs.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,166 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!--=========================================================================
+
+ Grouped links for Boost Libraries documentation
+
+ Copyright (c) 2007 Matias Capeletto
+
+ 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)
+
+===========================================================================-->
+
+
+<groupedLinks version="1.0">
+
+<title tag="Boost Libraries" url="index.html" />
+
+<group tag="Text processing" url="index.html" >
+<!--=======================================================================-->
+ <item tag="lexical_cast" url="conversion/lexical_cast.htm" />
+ <item tag="format" url="format/index.html" />
+ <item tag="iostreams" url="iostreams/doc/index.html" />
+ <item tag="regex" url="regex/index.html" />
+ <item tag="spirit" url="spirit/index.html" />
+ <item tag="string_algo" url="algorithm/string/index.html" />
+ <item tag="tokenizer" url="tokenizer/index.html" />
+ <item tag="wave" url="wave/index.html" />
+ <item tag="xpressive" url="xpressive/index.html" />
+
+</group>
+
+
+<group tag="Data structures" url="index.html" >
+<!--=======================================================================-->
+ <item tag="any" url="any/index.html" />
+ <item tag="array" url="array/index.html" />
+ <item tag="bimap" url="http://tinyurl.com/22sja5" />
+ <item tag="compressed_pair" url="utility/compressed_pair.htm" />
+ <item tag="dynamic_bitset" url="dynamic_bitset/dynamic_bitset.html" />
+ <item tag="graph" url="graph/doc/table_of_contents.html" />
+ <item tag="multi_array" url="multi_array/doc/index.html" />
+ <item tag="multi_index" url="multi_index/doc/index.html" />
+ <item tag="optional" url="libs/optional/doc/optional.html" />
+ <item tag="ptr_container" url="ptr_container/index.html" />
+ <item tag="property_map" url="property_map/property_map.html" />
+ <item tag="tribool" url="doc/html/tribool.html" />
+ <item tag="tuple" url="tuple/doc/tuple_users_guide.html" />
+ <item tag="variant" url="variant/index.html" />
+
+</group>
+
+
+<group tag="Algorithms" url="index.html" >
+<!--=======================================================================-->
+ <item tag="foreach" url="foreach/index.html" />
+ <item tag="minmax" url="algorithm/minmax/index.html" />
+ <item tag="range" url="range/index.html" />
+
+</group>
+
+
+<group tag="Functional" url="index.html" >
+<!--=======================================================================-->
+ <item tag="bind" url="bind/bind.html" />
+ <item tag="function" url="function/index.html" />
+ <item tag="functional" url="functional/index.htm" />
+ <item tag="hash" url="functional/hash/index.html" />
+ <item tag="lambda" url="lambda/index.html" />
+ <item tag="bind" url="bind/ref.html" />
+ <item tag="signals" url="signals/index.html" />
+ <item tag="result_of" url="utility/utility.htm#result_of" />
+
+</group>
+
+
+<group tag="Generic Programming" url="index.html" >
+<!--=======================================================================-->
+ <item tag="call_traits" url="utility/call_traits.htm" />
+ <item tag="concept_check" url="concept_check/concept_check.htm" />
+ <item tag="enable_if" url="utility/enable_if.html" />
+ <item tag="in_place_factory" url="utility/in_place_factories.html" />
+ <item tag="iterators" url="iterator/doc/index.html" />
+ <item tag="operators" url="utility/operators.htm" />
+ <item tag="typeof" url="typeof/index.html" />
+
+</group>
+
+
+<group tag="Metaprogramming" url="index.html" >
+<!--=======================================================================-->
+ <item tag="mpl" url="mpl/doc/index.html" />
+ <item tag="static_assert" url="static_assert/static_assert.htm" />
+ <item tag="type_traits" url="type_traits/index.html" />
+
+</group>
+
+
+<group tag="Concurrent" url="index.html" >
+<!--=======================================================================-->
+ <item tag="thread" url="thread/doc/index.html" />
+
+</group>
+
+
+<group tag="Math and numerics" url="index.html" >
+<!--=======================================================================-->
+ <item tag="math" url="math/doc/index.html" />
+ <item tag="conversion" url="numeric/conversion/index.html" />
+ <item tag="integer" url="integer/index.html" />
+ <item tag="interval" url="numeric/interval/doc/interval.htm" />
+ <item tag="random" url="random/index.html" />
+ <item tag="rational" url="rational/index.html" />
+ <item tag="ublas" url="numeric/ublas/doc/index.htm" />
+
+</group>
+
+
+<group tag="Input Output" url="index.html" >
+<!--=======================================================================-->
+ <item tag="io state savers" url="io/doc/ios_state.html" />
+ <item tag="program_options" url="../doc/html/program_options.html" />
+ <item tag="serialization" url="serialization/doc/index.html" />
+
+</group>
+
+
+<group tag="Memory" url="index.html" >
+<!--=======================================================================-->
+ <item tag="pool" url="pool/doc/index.html" />
+ <item tag="smart_ptr" url="smart_ptr/index.html" />
+ <item tag="utility" url="utility/utility.htm" />
+
+</group>
+
+
+<group tag="Miscellaneous" url="index.html" >
+<!--=======================================================================-->
+ <item tag="assign" url="assign/index.html" />
+ <item tag="base from member" url="utility/base_from_member.html" />
+ <item tag="crc" url="crc/index.html" />
+ <item tag="date_time" url="date_time/doc/index.html" />
+ <item tag="filesystem" url="filesystem/doc/index.htm" />
+ <item tag="parameter" url="parameter/doc/html/index.html" />
+ <item tag="preprocesor" url="preprocessor/doc/index.html" />
+ <item tag="python" url="python/doc/index.html" />
+ <item tag="timer" url="timer/index.html" />
+ <item tag="tr1" url="tr1/index.html" />
+ <item tag="statechart" url="statechart/doc/index.html" />
+ <item tag="value_initialized" url="utility/value_init.htm" />
+
+</group>
+
+
+<group tag="Compiler workarounds" url="index.html" >
+<!--=======================================================================-->
+ <item tag="compatibility" url="compatibility/index.html" />
+ <item tag="config" url="config/config.htm" />
+
+</group>
+
+
+
+</groupedLinks>
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/simple.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/example/simple/simple.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,46 @@
+<!--===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+============================================================================-->
+
+<html>
+
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
+<title>Boost.GroupedLinks Example</title>
+<link rel="stylesheet" href="../../css/grouped_links.css" type="text/css">
+</head>
+
+<body>
+
+<!-- Include the grouped links java script api -->
+
+<script type="text/javascript" src="../../../grouped_links.js"></script>
+
+<!-- Add a div with an unique "id" attribute -->
+
+<form id="boost_libs_list">
+
+ <!-- Call the GroupedLinks "select box" with the following parameters
+ (1) GroupedLinks xml definition url
+ (2) form id
+ (3) base url for the links
+ (4) selected item [optional] -->
+
+ <script type="text/javascript">
+
+ grouped_links_select_box('boost_libs.xml',
+ 'boost_libs_list',
+ 'http://www.boost.org/libs/');
+
+ </script>
+
+</form>
+
+</body>
+</html>
+
+
Added: sandbox/libpoet/trunk/doc/javascript/nested_links/index.html
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/nested_links/index.html 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,10 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+ <head>
+ <meta http-equiv="refresh" content="0; URL=doc/html/index.html">
+ </head>
+ <body>
+ Automatic redirection failed, click this
+ link
+ </body>
+</html>
Added: sandbox/libpoet/trunk/doc/javascript/style_switcher.js
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/style_switcher.js 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,157 @@
+/*===========================================================================
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+===========================================================================*/
+
+/* Requires: common.js */
+/* Requires: cookies.js */
+/* Requires: load_file.js */
+
+(function() {
+
+/* Based on http://alistapart.com/stories/alternate/ */
+
+function set_active_stylesheet(sSelected)
+{
+ var aLinks = document.getElementsByTagName('link');
+ for(var i = 0, len = aLinks.length; i < len; i++)
+ {
+ var oLink = aLinks[i];
+ var sTitle = oLink.getAttribute('title');
+ if( oLink.getAttribute('rel').indexOf('style') != -1 && sTitle )
+ {
+ oLink.disabled = true;
+ if ( sTitle == sSelected )
+ {
+ oLink.disabled = false;
+ }
+ }
+ }
+}
+
+function get_active_stylesheet()
+{
+ var aLinks = document.getElementsByTagName('link');
+ for(var i = 0; i < aLinks.length; i++)
+ {
+ var oLink = aLinks[i];
+ var sTitle = oLink.getAttribute('title');
+ if( oLink.getAttribute('rel').indexOf('style') != -1 &&
+ sTitle && ! oLink.disabled )
+ {
+ return sTitle;
+ }
+ }
+ return null;
+}
+
+function get_preferred_stylesheet()
+{
+ var aLinks = document.getElementsByTagName('link');
+ for(var i = 0; i < aLinks.length; i++)
+ {
+ var oLink = aLinks[i];
+ var sTitle = oLink.getAttribute('title');
+ var oRel = oLink.getAttribute('rel');
+ if( oRel.indexOf('style') != -1 &&
+ oRel.indexOf('alt' ) == -1 &&
+ sTitle )
+ {
+ return sTitle;
+ }
+ }
+ return null;
+}
+
+function include_alternate_stylesheets(sXmlUrl,sUserBaseUrl)
+{
+ boostscript.load_file.load_xml(sXmlUrl, function(oXml) {
+
+ var sBaseUrl = sUserBaseUrl ?
+ boostscript.common.format_base_url( sUserBaseUrl ) : './';
+
+ var oBaseUrlNode = oXml.getElementsByTagName('base')[0];
+ if( oBaseUrlNode != null )
+ {
+ sBaseUrl += boostscript.common.format_base_url(
+ oBaseUrlNode.getAttribute('href')
+ );
+ }
+
+ var oHead = document.getElementsByTagName("head")[0];
+
+ var aStyles = oXml.getElementsByTagName('style');
+ for( var i = 0, len = aStyles.length; i < len ; i++ )
+ {
+ var oStyle = aStyles[i];
+ var sPref = oStyle.getAttribute('preferred');
+ var bPreferred = sPref ? sPref == 'true' : false;
+
+ var cssNode = document.createElement('link');
+
+ cssNode.type = 'text/css';
+ cssNode.rel = ( (!bPreferred) ? 'alternate ' : '' ) + 'stylesheet';
+ cssNode.href = boostscript.common.format_url(
+ oStyle.getAttribute('href'),sBaseUrl
+ );
+ cssNode.title = oStyle.getAttribute('title')
+
+ oHead.appendChild(cssNode);
+ }
+
+ }, true );
+}
+
+function insert_style_selector(sId,sXmlUrl)
+{
+ boostscript.load_file.load_xml(sXmlUrl, function(oXml) {
+
+ var sStyleSwitcherBox = '<div class="ss-options">' ;
+
+ var aStyles = oXml.getElementsByTagName('style');
+ for( var i = 0, len = aStyles.length; i < len ; i++ )
+ {
+ var sTitle = aStyles[i].getAttribute('title');
+ sStyleSwitcherBox += '<a href="#" ' +
+ 'onclick="boostscript.style_switcher.set_active_stylesheet(\'' +
+ sTitle +
+ '\'); return false;" >' +
+ '<div class="ss-option-' + sTitle + '">' +
+ '</div>' +
+ '</a>' ;
+ }
+
+ document.getElementById(sId).innerHTML = sStyleSwitcherBox + '</div>';
+
+ }, true );
+}
+
+function load_user_stylesheet(e)
+{
+ var sCookie = boostscript.cookies.read('style');
+ set_active_stylesheet( sCookie ? sCookie : get_preferred_stylesheet() );
+}
+
+function save_user_stylesheet(e)
+{
+ boostscript.cookies.create( 'style', get_active_stylesheet(), 365 );
+}
+
+window.onload = load_user_stylesheet;
+window.onunload = save_user_stylesheet;
+
+// Public Interface
+
+boostscript.style_switcher.include_alternate_stylesheets = include_alternate_stylesheets;
+boostscript.style_switcher.insert_style_selector = insert_style_selector;
+boostscript.style_switcher.set_active_stylesheet = set_active_stylesheet;
+boostscript.style_switcher.load_user_stylesheet = load_user_stylesheet;
+
+boostscript.style_switcher.loaded = true;
+
+})();
+
+
Added: sandbox/libpoet/trunk/doc/javascript/style_switcher/doc/TODO
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/javascript/style_switcher/doc/TODO 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1 @@
+
Added: sandbox/libpoet/trunk/doc/style/html/blurbs.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/blurbs.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,113 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Table
+-----------------------------------------------------------------------------*/
+
+
+
+
+ .note,
+ .tip,
+ .important,
+ .caution,
+ .warning,
+ .sidebar
+ {
+ font-size: 10pt;
+ line-height: 1.2;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ }
+
+ .sidebar .box-inner-wrapper
+ {
+ padding-left: 28px;
+ }
+
+ .sidebar .box-inner-wrapper img
+ {
+ padding: 1pt;
+ }
+
+ .admonition-body
+ {
+ padding-left: 50px;
+ }
+
+ .admonition-graphic
+ {
+ float: left;
+ display: inline;
+ padding-top: 5px;
+ }
+
+ .admonition-title
+ {
+ font-weight: bold;
+ }
+
+ .admonition-content
+ {
+
+ }
+
+ .admonition-icon
+ {
+ border: none;
+ }
+
+ .note-icon { background: url(images/admonitions/note.png)
+ no-repeat center;
+ height: 30px; width: 30px; }
+
+ .warning-icon { background: url(images/admonitions/warning.png)
+ no-repeat center;
+ height: 30px; width: 30px; }
+
+ .caution-icon { background: url(images/admonitions/caution.png)
+ no-repeat center;
+ height: 30px; width: 30px; }
+
+ .tip-icon { background: url(images/admonitions/tip.png)
+ no-repeat center;
+ height: 30px; width: 30px; }
+
+ .important-icon { background: url(images/admonitions/important.png)
+ no-repeat center;
+ height: 30px; width: 30px; }
+
+
+ /* --- IE6 patch using the star hack --- */
+
+ * html body .note-icon { background: url(images/admonitions/solid/note.png)
+ no-repeat center; }
+
+ * html body .warning-icon { background: url(images/admonitions/solid/warning.png)
+ no-repeat center; }
+
+ * html body .caution-icon { background: url(images/admonitions/solid/caution.png)
+ no-repeat center; }
+
+ * html body .tip-icon { background: url(images/admonitions/solid/tip.png)
+ no-repeat center; }
+
+ * html body .important-icon { background: url(images/admonitions/solid/important.png)
+ no-repeat center; }
+
Added: sandbox/libpoet/trunk/doc/style/html/box_wrapper.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/box_wrapper.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,153 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Box Wrapper
+-----------------------------------------------------------------------------*/
+
+
+ .box-outer-wrapper
+ {
+ border: 2px solid #EAEEEB;
+ border-bottom: none;
+ border-top: none;
+ background-color: white;
+ /* options:
+ (white) white;
+ (green) #FAFFFB;
+ */
+ }
+
+ .box-outer-wrapper:hover
+ {
+ background-color: #FAFFFB;
+ /* options:
+ (green ) #FAFFFB;
+ (orange) #FEFFF5;
+ (blue ) #FBFBFF;
+ */
+ }
+
+ .box-top-left
+ {
+ float: left;
+ margin-left: -2px;
+ min-height: 18px;
+ min-width: 18px;
+ background: url(images/box_wrapper/top-left.png) no-repeat top left;
+ }
+
+ .box-top-right
+ {
+ margin-right: -2px;
+ min-height: 18px;
+ min-width: 18px;
+ background: url(images/box_wrapper/top-right.png) no-repeat top right;
+ float: right;
+ }
+
+ .box-top
+ {
+ min-height: 18px;
+ background: url(images/box_wrapper/top.png) repeat-x top;
+ }
+
+ .box-inner-wrapper
+ {
+ padding-left: 18px;
+ }
+
+ .box-bottom-left
+ {
+ margin-left: -2px;
+ min-height: 28px;
+ min-width: 18px;
+ background: url(images/box_wrapper/bottom-left.png) no-repeat bottom left;
+ float: left;
+ }
+ .box-bottom-right
+ {
+ margin-right: -2px;
+ min-height: 28px;
+ min-width: 18px;
+ background: url(images/box_wrapper/bottom-right.png) no-repeat bottom right;
+ float: right;
+ }
+
+ .box-bottom
+ {
+ min-height: 28px;
+ background: url(images/box_wrapper/bottom.png) repeat-x bottom;
+ }
+
+
+ /* --- IE6 patch using the star hack --- (Thanks to Daniel James) */
+
+
+ * html body .box-top-left
+ {
+ background: url(images/box_wrapper/solid/top-left.png) no-repeat top left;
+ display: inline;
+ height: 18px;
+ width: 18px;
+ }
+
+ * html body .box-top-right
+ {
+ background: url(images/box_wrapper/solid/top-right.png) no-repeat top right;
+ display: inline;
+ height: 18px;
+ width: 18px;
+ }
+
+ * html body .box-top
+ {
+ background: url(images/box_wrapper/solid/top.png) repeat-x top;
+ height: 18px;/*
+ margin-left: -2px;
+ margin-right: -2px;
+ padding-left: -2px;
+ padding-right: -2px;*/
+ }
+
+ * html body .box-bottom-left
+ {
+ background: url(images/box_wrapper/solid/bottom-left.png) no-repeat bottom left;
+ display: inline;
+ height: 28px;
+ width: 18px;
+ margin-right: -3px;
+ }
+
+ * html body .box-bottom-right
+ {
+ background: url(images/box_wrapper/solid/bottom-right.png) no-repeat bottom right;
+ display: inline;
+ height: 28px;
+ width: 18px;
+ margin-left: -3px;
+ }
+
+ * html .box-bottom
+ {
+ background: url(images/box_wrapper/solid/bottom.png) repeat-x bottom;
+ height: 28px;
+ }
+
+
\ No newline at end of file
Added: sandbox/libpoet/trunk/doc/style/html/callouts.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/callouts.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,53 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+
+/*----------------------------------------------------------------------------
+ Callouts
+-----------------------------------------------------------------------------*/
+
+
+ .calloutlist
+ {
+ padding-left: 75px;
+ padding-bottom: 10px;
+ }
+
+ .line_callout_bug img
+ {
+ float: left;
+ position:relative;
+ left: -18px;
+ top: -12px;
+ clear: left;
+ margin-left:-22px;
+ border: none;
+ }
+
+ .callout_bug a img
+ {
+ border: none;
+ }
+
+ .calloutlist dl dt a img
+ {
+ float: left;
+ border: none;
+ }
+
Added: sandbox/libpoet/trunk/doc/style/html/conversion/boostbook_to_quickbook.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/conversion/boostbook_to_quickbook.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,607 @@
+/*=============================================================================
+
+ Html To Quickbook stylesheets
+
+ Copyright (c) 2006 Rene Rivera
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+=============================================================================*/
+
+/* Import common quickbook structures
+-----------------------------------------------------------------------------*/
+
+@import url(quickbook_common.css);
+@import url(../syntax/kd.css);
+
+/* Include again some boostbook stylesheet settings to allow site navigation
+-----------------------------------------------------------------------------*/
+
+/* Header */
+
+/* Spirit navigation bar */
+
+.spirit-nav a::before, .spirit-nav a::after
+{
+ content: "";
+}
+
+/* footer */
+
+#footer a::before, #footer a::after
+{
+ content: "";
+}
+
+
+/* Remove boostbook style
+-----------------------------------------------------------------------------*/
+
+/* General */
+
+#body
+{
+ border: none;
+ margin: 20px;
+ padding: 0em;
+ text-indent: 0em;
+ color: black;
+ font-size: 10pt;
+ font-weight: normal;
+ font-style: normal;
+ text-decoration: none;
+ font-family: monospace;
+ background: white;
+ background-color: white;
+}
+
+p
+{
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.15;
+}
+
+/* headings */
+
+.titlepage
+{
+ line-height: 1.15;
+}
+
+.titlepage .title
+{
+ margin-bottom: 0px;
+}
+
+.titlepage .copyright
+{
+ margin-top: 0px;
+}
+
+.titlepage_logo
+{
+ display: none;
+}
+
+.titlepage_separator
+{
+ margin-bottom: 0px;
+}
+
+.section
+{
+ margin-bottom: 0px;
+}
+/*
+h1, h2, h3, h4, h5, h6,
+.title, h1 .title, h2 .title, h3 .title, h4 .title, h5 .title, h6 .title,
+.section h1, .section h2, .section h3, .section h4, .section h5, .section h6,
+.refentrytitle,
+h1 tt .computeroutput, h2 tt .computeroutput, h3 tt .computeroutput,
+h4 tt .computeroutput, h5 tt .computeroutput, h6 tt .computeroutput
+*/
+
+#body p,
+#body .title,
+#body .section > h1,
+#body .section > h2,
+#body .section > h3,
+#body .section > h4,
+#body .section > h5,
+#body .section > h6,
+#body .section
+{
+ line-height: 1.5;
+ text-align: left;
+ margin: 0px;
+ padding: 0px;
+ font-weight: normal;
+ font: 100%;
+ font-size: 10pt;
+ color: black;
+ border: none;
+ text-decoration: none;
+ font-family: monospace;
+}
+
+#body .section .title
+{
+ padding-bottom: 20px;
+}
+
+#body .section::after
+{
+ line-height: 60px;
+}
+
+/* Box wrapper */
+
+.box-outer-wrapper
+{
+ border: none;
+ margin: 0px;
+ padding: 0px;
+}
+
+.box-outer-wrapper:hover
+{
+ background-color: white;
+ margin: 0px;
+ padding: 0px;
+}
+
+.box-top-left,
+.box-top-right,
+.box-top,
+.box-bottom-left,
+.box-bottom-right,
+.box-bottom
+{
+ display: none;
+}
+
+.box-inner-wrapper
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+/* Remove toc */
+
+.toc
+{
+ display: none;
+}
+
+/* Remove footnotes */
+
+.footnotes
+{
+ display: none;
+}
+
+/* Tables */
+
+.table-title, .table p .title
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+.table table,
+.informaltable table
+{
+ width: 100%;
+ margin: 0px;
+ padding: 0px;
+}
+
+.table table tr th,
+.informaltable table tr th,
+.table table tr th p,
+.informaltable table tr th p,
+.table table tr td,
+.informaltable table tr td,
+.table table tr td p,
+.informaltable table tr td p
+{
+ margin: 0px;
+ padding: 0px;
+ background-color: white;
+ border: none;
+ font-size: 10pt;
+ text-align: left;
+ line-height: 1.15;
+ display: inline;
+}
+
+.table table:hover tr th,
+.informaltable table:hover tr th
+{
+ background-color: white;
+}
+
+.table table:hover tr td,
+.informaltable table:hover tr td
+{
+ background-color: white;
+}
+
+
+/* code */
+
+#body .programlisting, #body .screen, #body .synopsis
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+/* Remove the style selectors */
+
+.style-switcher-box
+{
+ display: none;
+}
+
+/* Remove numbers from lists */
+
+.ol_1, .ol_a, .ol_i, .ol_A, .ol_I { list-style-type: none; }
+
+li,
+ul,
+ol
+{
+ padding: 0px;
+ margin: 0px;
+}
+
+li ul,
+li ol
+{
+ padding-left: 35px;
+}
+
+
+/* Overwritte some boostbook style
+-----------------------------------------------------------------------------*/
+
+#body a::before { content: "[@" attr(href) " "; color: #5555FF; }
+#body a::after { content: "]"; color: #5555FF; }
+#body a
+{
+ color: black;
+}
+
+#body blockquote::before, #body blockquote::after { content: ""; }
+
+div .blockquote::before { content: "[:"; color: #5555FF; }
+div .blockquote::after { content: "]"; color: #5555FF; }
+
+/* Add more quickbook related style
+-------------------------------------------------------------------------------*/
+
+/* Sections */
+
+.section .titlepage .title::before
+{
+ content: "[section ";
+ color: #5555FF;
+ font-weight: normal;
+}
+
+.section .titlepage .title::after
+{
+ content: "]";
+ color: #5555FF;
+ font-weight: normal;
+}
+
+.section .titlepage .title a
+{
+ font-weight: bold;
+}
+
+.section::after
+{
+ content: "[endsect]";
+ color: #5555FF;
+}
+
+.section a::before, .section a::after
+{
+ content: "";
+}
+
+/* Headings */
+
+
+#body .section > h1::before,
+#body .section > h2::before,
+#body .section > h3::before,
+#body .section > h4::before,
+#body .section > h5::before,
+#body .section > h6::before
+{
+ content: "[heading ";
+ color: #5555FF;
+ font-weight: normal;
+}
+
+#body .section > h1::after,
+#body .section > h2::after,
+#body .section > h3::after,
+#body .section > h4::after,
+#body .section > h5::after,
+#body .section > h6::after
+{
+ content: "]";
+ color: #5555FF;
+ font-weight: normal;
+}
+
+#body .section > h1,
+#body .section > h2,
+#body .section > h3,
+#body .section > h4,
+#body .section > h5,
+#body .section > h6
+{
+ font-weight: bold;
+ color: #5555FF;
+}
+
+
+#body .section > h1 a::before,
+#body .section > h2 a::before,
+#body .section > h3 a::before,
+#body .section > h4 a::before,
+#body .section > h5 a::before,
+#body .section > h6 a::before,
+#body .section > h1 a::after,
+#body .section > h2 a::after,
+#body .section > h3 a::after,
+#body .section > h4 a::after,
+#body .section > h5 a::after,
+#body .section > h6 a::after,
+#body .section > a::before,
+#body .section > a::before,
+#body .section > a::before,
+#body .section > a::before,
+#body .section > a::before,
+#body .section > a::before,
+#body .section > a::after,
+#body .section > a::after,
+#body .section > a::after,
+#body .section > a::after,
+#body .section > a::after,
+#body .section > a::after,
+#body .section .titlepage .title a::before,
+#body .section .titlepage .title a::after
+{
+ content: "";
+}
+
+
+/* Tables */
+
+.table table tr th,
+.informaltable table tr th,
+.table table tr th p,
+.informaltable table tr th p
+{
+ background-color: #E6E6E6;
+}
+
+table::before { content: ""; }
+
+.table .title::before { content: "[table "; color: #5555FF; font-style: normal; }
+#body .table .title b::before { content: ""; }
+#body .table .title b::after { content: ""; }
+
+#body .table > a { display: none; }
+
+/* Code */
+
+
+.computeroutput::before,
+.computeroutput::after { content: "`"; color: #5555FF; font-style: normal; }
+
+.programlisting .box-inner-wrapper::before,
+.programlisting pre::after { content: "``"; color: #5555FF; font-style: normal; }
+
+.programlisting pre::before { content: ""; }
+
+.synopsis .box-inner-wrapper,
+.programlisting .box-inner-wrapper,
+.screen .box-inner-wrapper
+{
+ margin: 0px;
+ padding: 0px;
+}
+
+.line_callout_bug,
+.callout_bug,
+.calloutlist { display: none; }
+
+
+/* Blurbs */
+
+
+.note,
+.tip,
+.important,
+.caution,
+.warning,
+.sidebar
+{
+ font-size: 10pt;
+ line-height: 1.15;
+ margin: 0px;
+ padding: 0px;
+}
+
+.sidebar .box-inner-wrapper,
+.sidebar .box-inner-wrapper img,
+.admonition-body
+{
+ padding: 0px;
+}
+
+.admonition-graphic
+{
+ display: none;
+}
+
+.admonition-title
+{
+ font-weight: normal;
+ color: #5555FF;
+}
+
+.admonition-title::before
+{
+ content: "[";
+}
+
+.admonition-body::after
+{
+ content: "]";
+ color: #5555FF;
+}
+
+.sidebar .box-inner-wrapper::before
+{
+ content: "[blurb ";
+ color: #5555FF;
+}
+
+.sidebar .box-inner-wrapper::after
+{
+ content: "] ";
+ color: #5555FF;
+}
+
+/* First page of the docs */
+
+
+#body .article a::before, #body .article a::after,
+#body .book a::before, #body .book a::after,
+#body .chapter a::before, #body .chapter a::after
+{
+ content: "";
+}
+
+.article .title::before,
+.book .title::before,
+.chapter .title::before
+{
+ content: "[article ";
+}
+
+#body .article .title,
+#body .book .title,
+#body .chapter .title
+{
+ font-weight: bold;
+}
+
+.article::after,
+.book::after,
+.chapter::after
+{
+ content: "]";
+}
+
+.article .titlepage::after,
+.book .titlepage::after,
+.chapter .titlepage::after
+{
+ padding-left: 35px;
+ content: "[purpose Unknown] [category Unknown] [quickbook 1.4]"
+}
+
+.authorgroup::before
+{
+ content: "[authors ";
+}
+
+.authorgroup::after
+{
+ content: "]";
+}
+
+.authorgroup div .author::before
+{
+ content: "[";
+}
+
+.authorgroup div .author::after
+{
+ content: "]";
+}
+
+.authorgroup div .author
+{
+ font-weight: normal;
+ line-height: 1.5;
+ padding: 0px;
+ margin: 0px;
+}
+
+.copyright::before
+{
+ content: "[copyright ";
+}
+
+.copyright::after
+{
+ content: "]";
+}
+
+div div.legalnotice p::before
+{
+ content: "[license ";
+}
+
+div div.legalnotice p::after
+{
+ content: "]";
+}
+
+.copyright,
+div div.legalnotice p
+{
+ color: black;
+ font-size: 10pt;
+ font-style: normal;
+ font-weight: normal;
+}
+
+#body .copyright,
+#body div div.legalnotice p,
+.authorgroup
+{
+ padding-left: 35px;
+}
+
+.article .title::before, .article::after,
+.authorgroup::before, .authorgroup::after,
+.authorgroup div .author::before, .authorgroup div .author::after,
+.copyright::before, .copyright::after,
+div div.legalnotice p::before, div div.legalnotice p::after,
+.article .titlepage::after
+{
+ color: #5555FF;
+ font-style: normal;
+ font-weight: normal;
+}
+
+.titlepage_separator
+{
+ display: none;
+}
+
Added: sandbox/libpoet/trunk/doc/style/html/conversion/html_to_quickbook.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/conversion/html_to_quickbook.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,185 @@
+/*=============================================================================
+
+ Html To Quickbook stylesheets
+
+ Copyright (c) 2006 Rene Rivera
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+=============================================================================*/
+
+@import url(html_to_quickbook_general.css);
+@import url(quickbook_common.css);
+
+/* General
+-----------------------------------------------------------------------------*/
+
+body, body *
+{
+ border: none;
+ margin: 0em;
+ padding: 0em;
+ text-indent: 0em;
+ color: black;
+ font-size: 10pt;
+ font-weight: normal;
+ font-style: normal;
+ text-decoration: none;
+ font-family: monospace;
+ background: white;
+ background-color: white;
+}
+
+body::before
+{
+ content: "[section Top]";
+ color: #5555FF;
+}
+
+body::after
+{
+ content: "[endsect]";
+ color: #5555FF;
+}
+
+h1 img, h2 img, h3 img, h4 img, h5 img, h6 img
+{
+ display: none;
+}
+
+/* Variable List
+-----------------------------------------------------------------------------*/
+
+dl::before { content: "[variablelist "; color: #5555FF; }
+dl::after { content: "]"; color: #5555FF; }
+dt::before { content: " [["; color: #5555FF; }
+dt::after { content: "]]"; color: #5555FF; }
+dd::before { content: "["; color: #5555FF; }
+dd::after { content: "]"; color: #5555FF; }
+
+/* Preformatted output and code
+-----------------------------------------------------------------------------*/
+
+pre::before { content: "[pre \A"; color: #5555FF; }
+pre::after { content: "\A]"; color: #5555FF; }
+code::before { content: "[^"; color: #5555FF; }
+code::after { content: "]"; color: #5555FF; }
+
+/* Text style
+-----------------------------------------------------------------------------*/
+
+i::before { content: "['"; color: #5555FF; font-style: normal; }
+i { font-style: italic; }
+i::after { content: "]"; color: #5555FF; font-style: normal; }
+
+b::before { content: "[*"; color: #5555FF; font-weight: normal; }
+b { font-weight: bold; }
+b::after { content: "]"; color: #5555FF; font-weight: normal; }
+
+u::before { content: "[_"; color: #5555FF; text-decoration: none; }
+u { text-decoration: underline; }
+u::after { content: "]"; color: #5555FF; text-decoration: none; }
+
+tt::before { content: "[^"; color: #5555FF; }
+tt::after { content: "]"; color: #5555FF; }
+
+q::before { content: "[\""; color: #5555FF; font-style: normal; }
+q { font-style: italic; }
+q::after { content: "\"]"; color: #5555FF; font-style: normal; }
+
+/* Lists
+-----------------------------------------------------------------------------*/
+
+blockquote > li::before { content: "* "; color: #5555FF; }
+ol > li::before { content: "# "; color: #5555FF; }
+ul > li::before { content: "* "; color: #5555FF; }
+ul > li { list-style: none; }
+
+/* Blockquote
+-----------------------------------------------------------------------------*/
+
+blockquote::before { content: "[:"; color: #5555FF; }
+blockquote::after { content: "]"; color: #5555FF; }
+
+/* Tables
+-----------------------------------------------------------------------------*/
+
+table { display: block; }
+tr { display: block; }
+td { display: inline; }
+th { display: inline; }
+
+table::before { content: "[table"; color: #5555FF; }
+table::after { content: "]"; color: #5555FF; }
+
+tr::before { content: "["; color: #5555FF; }
+tr::after { content: "]"; color: #5555FF; }
+td::before { content: "["; color: #5555FF; }
+td::after { content: "]"; color: #5555FF; }
+th::before { content: "["; color: #5555FF; }
+th::after { content: "]"; color: #5555FF; }
+
+/* Forms
+-----------------------------------------------------------------------------*/
+
+form { display: none; }
+
+/* Links
+-----------------------------------------------------------------------------*/
+
+a::before { content: "[@" attr(href) " "; color: #5555FF; }
+a::after { content: "]"; color: #5555FF; }
+
+/* Sections and Headings
+-----------------------------------------------------------------------------*/
+
+h1, h2, h3, h4, h5, h6, p, pre, dl, ul, blockquote {
+ margin-top: 1em;
+}
+
+h1::before, h2::before, h3::before, h4::before, h5::before, h6::before
+{
+ content: "[endsect] [/br][/br] [section ";
+ color: #5555FF;
+}
+
+h1::after, h2::after, h3::after, h4::after, h5::after, h6::after
+{
+ content: "]";
+ color: #5555FF;
+}
+
+h1 a::before, h2 a::before, h3 a::before, h4 a::before, h5 a::before, h6 a::before,
+h1 a::after, h2 a::after, h3 a::after, h4 a::after, h5 a::after, h6 a::after
+{
+ content: "";
+}
+
+/* Images
+-----------------------------------------------------------------------------*/
+
+/* TODO
+img::before
+{
+ content: "[$" attr(src);
+ color: #5555FF;
+}
+
+img::after
+{
+ content: "]";
+ color: #5555FF;
+}
+
+
+*/
+
+img
+{
+ max-height: 100px;
+ max-width: 100px;
+ overflow: hidden;
+}
Added: sandbox/libpoet/trunk/doc/style/html/conversion/html_to_quickbook_general.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/conversion/html_to_quickbook_general.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,52 @@
+/*=============================================================================
+
+ Html To Quickbook stylesheets
+
+ Copyright (c) 2006 Rene Rivera
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+=============================================================================*/
+
+
+@import url(quickbook_common.css)
+
+/* General
+-----------------------------------------------------------------------------*/
+
+body, body *
+{
+ border: none;
+ margin: 0em;
+ padding: 0em;
+ text-indent: 0em;
+ color: black;
+ font-size: 10pt;
+ font-weight: normal;
+ font-style: normal;
+ text-decoration: none;
+ font-family: monospace;
+ background: white;
+ background-color: white;
+}
+
+body::before
+{
+ content: "[section Top]";
+ color: #5555FF;
+}
+
+body::after
+{
+ content: "[endsect]";
+ color: #5555FF;
+}
+
+h1 img, h2 img, h3 img, h4 img, h5 img, h6 img
+{
+ display: none;
+}
+
Added: sandbox/libpoet/trunk/doc/style/html/conversion/quickbook_common.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/conversion/quickbook_common.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,152 @@
+/*=============================================================================
+
+ Html To Quickbook stylesheets
+
+ Copyright (c) 2006 Rene Rivera
+ Copyright (c) 2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+=============================================================================*/
+
+/* General
+-----------------------------------------------------------------------------*/
+
+
+/* Variable List
+-----------------------------------------------------------------------------*/
+
+dl::before { content: "[variablelist "; color: #5555FF; font-weight:normal; }
+dl::after { content: "]"; color: #5555FF; font-weight:normal; }
+dt::before { content: " [["; color: #5555FF; font-weight:normal; }
+dt { font-weight:bold; }
+dt::after { content: "]"; color: #5555FF; font-weight:normal; }
+dd::before { content: "["; color: #5555FF; font-weight:normal; }
+dd::after { content: "]]"; color: #5555FF; font-weight:normal; }
+
+/* Preformatted output and code
+-----------------------------------------------------------------------------*/
+
+pre::before { content: "[pre \A"; color: #5555FF; }
+pre::after { content: "\A]"; color: #5555FF; }
+code::before { content: "[^"; color: #5555FF; }
+code::after { content: "]"; color: #5555FF; }
+
+/* Text style
+-----------------------------------------------------------------------------*/
+
+i::before, .emphasis::before { content: "['"; }
+i, .emphasis { font-style: italic; }
+i::after, .emphasis::after { content: "]"; }
+
+b::before, .bold::before { content: "[*"; }
+b, .bold { font-weight: bold; }
+b::after, .bold::after { content: "]"; }
+
+u::before, .underline::before { content: "[_"; }
+u, .underline { text-decoration: underline; }
+u::after, .underline::after { content: "]"; }
+
+tt::before, .literal::before { content: "[^"; }
+tt, .literal { font-style: normal; }
+tt::after, .literal::after { content: "]"; }
+
+q::before, .quote::before { content: "[\""; }
+q::after, .quote::after { content: "\]"; }
+
+.strikethrough::before { content: "[-"; }
+.strikethrough { text-decoration: strikethrough; }
+.strikethrough::after { content: "]"; }
+
+.replaceable code::before { content: "[~"; }
+.replaceable code { font-style: italic; }
+.replaceable code::after { content: "]"; }
+
+i::before, i::after, .emphasis::before, .emphasis::after,
+b::before, b::after, .bold::before, .bold::after,
+u::before, u::after, .underline::before, .underline::after,
+tt::before, tt::after, .literal::before, .literal::after,
+q::before, q::after, .quote::before,.quote::after,
+.strikethrough::before, .strikethrough::after,
+.replaceable code::before, .replaceable code::after
+{
+ font-style: normal;
+ font-weight: normal;
+ text-decoration: none;
+ color: #5555FF;
+}
+
+
+
+
+
+/* Lists
+-----------------------------------------------------------------------------*/
+
+blockquote > li::before { content: "* "; color: #5555FF; }
+ol > li::before { content: "# "; color: #5555FF; }
+ul > li::before { content: "* "; color: #5555FF; }
+ul > li { list-style: none; }
+
+/* Blockquote
+-----------------------------------------------------------------------------*/
+
+blockquote::before { content: "[:"; color: #5555FF; }
+blockquote::after { content: "]"; color: #5555FF; }
+
+/* Tables
+-----------------------------------------------------------------------------*/
+
+table { display: block; }
+tr { display: block; }
+td { display: inline; }
+th { display: inline; }
+
+table::before { content: "[table"; color: #5555FF; }
+table::after { content: "]"; color: #5555FF; }
+
+tr::before { content: "["; color: #5555FF; font-weight: normal; }
+tr::after { content: "]"; color: #5555FF; font-weight: normal; }
+td::before { content: "["; color: #5555FF; font-weight: normal; }
+td::after { content: "]"; color: #5555FF; font-weight: normal; }
+th::before { content: "["; color: #5555FF; font-weight: normal;
+ background-color: white; }
+th { font-weight: bold; background-color: #E6E6E6; }
+th::after { content: "]"; color: #5555FF; font-weight: normal;
+ background-color: white; }
+
+/* Links
+-----------------------------------------------------------------------------*/
+
+a::before { content: "[@" attr(href) " "; color: #5555FF; }
+a::after { content: "]"; color: #5555FF; }
+
+/* Sections and Headings
+-----------------------------------------------------------------------------*/
+
+
+
+/* Images
+-----------------------------------------------------------------------------*/
+
+img::before
+{
+ content: "[$" attr(src);
+ color: #5555FF;
+}
+
+img::after
+{
+ content: "]";
+ color: #5555FF;
+}
+
+img
+{
+ max-height: 300px;
+ max-width: 500px;
+ overflow: hidden;
+}
+
Added: sandbox/libpoet/trunk/doc/style/html/footer.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/footer.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,69 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Footer
+-----------------------------------------------------------------------------*/
+
+
+ #footer {
+ color: #666666;
+ margin: 1.5em;
+ padding: 0em;
+ clear: both;
+ background: #FFFFFF url(images/footer/background.png) repeat-x top left;
+ border: none;
+ }
+
+ #footer-left {
+ float: left;
+ padding: 0.65em;
+ min-height: 100px;
+ background: url(images/footer/background-left.png) no-repeat top left;
+ }
+
+ #footer-right {
+ float: right;
+ padding: 0.65em;
+ min-height: 100px;
+ background: url(images/footer/background-right.png) no-repeat top right;
+ }
+
+ #footer p {
+ margin: 0em;
+ padding: 0em;
+ font-size: 75%;
+ text-align: left;
+ }
+
+ #footer #banners p {
+ float: left;
+ margin: 0em 0em 0em 1em;
+ }
+
+ #footer #banners a {
+ display: block;
+ }
+
+ #footer #banner-sourceforge {
+ /*background: url(http://sourceforge.net/sflogo.php?group_id=7586&type=1) no-repeat fixed 0px 5em;*/
+ }
+
+
+
Added: sandbox/libpoet/trunk/doc/style/html/general.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/general.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,110 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ General
+-----------------------------------------------------------------------------*/
+
+
+ .clear
+ {
+ clear : both;
+ width : 100%;
+ height : 1px;
+ overflow : hidden;
+ }
+
+ body
+ {
+ font-family: sans-serif;
+ min-width : 43em;
+ margin: 0;
+ }
+
+ #body
+ {
+ clear : both;
+ border : none;
+ width : 100%;
+ background : #ffffff;
+ }
+
+ #content
+ {
+ margin: 1em;
+ clear : both;
+ border : none;
+ }
+
+ p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.3;
+ margin: 0em 0em 0.8em 0em;
+ }
+
+
+ a
+ {
+ text-decoration: none;
+ border: none;
+ color: #0C7445;
+ }
+
+ a:hover { text-decoration: underline; }
+ a:visited { color: #663974; }
+
+
+ span.title { font-style: italic; }
+ span.underline { text-decoration: underline; }
+ span.strikethrough { text-decoration: line-through; }
+ span.highlight { color: #00A000; }
+ div div.legalnotice p { text-align: left; color: #666666; }
+ .copyright { font-size: small; color: #666666; }
+
+
+ .titlepage
+ {
+ line-height: 0.6;
+ }
+
+ .titlepage .title
+ {
+ margin-bottom: 30px;
+ }
+
+ .titlepage .copyright
+ {
+ margin-top: 30px;
+ }
+
+ .titlepage_logo
+ {
+ text-align: center;
+ }
+
+ .titlepage_separator
+ {
+ margin-bottom: 30px;
+ }
+
+ .section
+ {
+ margin-bottom: 20px;
+ }
Added: sandbox/libpoet/trunk/doc/style/html/header.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/header.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,90 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Page Header
+-----------------------------------------------------------------------------*/
+
+
+ @import url(nested_links.css);
+
+ body
+ {
+ background: #ffffff url(images/header/background-more.png) repeat-x top left;
+ color: black;
+ }
+
+ #heading
+ {
+ height: 100px;
+ background: url(images/header/background.png) no-repeat top left;
+ border-bottom: solid 1px;
+ }
+
+ .heading-logo
+ {
+ text-align: left;
+ border: none;
+ }
+
+ div.search-box
+ {
+ text-align: right;
+ padding-bottom: 10px;
+ padding-right: 10px;
+ height: 40px;
+ color: white;
+ font-weight: bold;
+ background : transparent;
+ }
+
+ input.search-box
+ {
+ background-color: #BEDEBA;
+ font-weight: bold;
+ font-size: 12px;
+ color: #006D00;
+ border: 1px solid #DCDCDC;
+ border-bottom: 1px solid #9D9D9D;
+ border-right: 1px solid #9D9D9D;
+ padding-bottom: 3px;
+ padding-left: 3px;
+ }
+
+ .heading-navigation-box
+ {
+ text-align: right;
+ padding-top: 10px;
+ padding-right: 10px;
+ height: 40px;
+ background : transparent;
+ }
+
+ .search-box-label::before
+ {
+ content: "Search Boost";
+ }
+
+ /* --- IE6 patch using the star hack --- (Thanks to Daniel James) */
+
+
+ * html body #heading
+ {
+ border-bottom: none;
+ }
Added: sandbox/libpoet/trunk/doc/style/html/headings.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/headings.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,93 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Headings
+-----------------------------------------------------------------------------*/
+
+ h1, h2, h3, h4, h5, h6
+ {
+ text-align: left;
+ margin: 1em 0em 0.5em 0em;
+ font-weight: bold;
+ }
+
+ h1 { font: 140% }
+ h2 { font: bold 140% }
+ h3 { font: bold 130% }
+ h4 { font: bold 120% }
+ h5 { font: italic 110% }
+ h6 { font: italic 100% }
+
+ /* Top page titles */
+ title,
+ h1.title,
+ h2.title,
+ h3.title,
+ h4.title,
+ h5.title,
+ h6.title,
+ .refentrytitle
+ {
+ font-weight: bold;
+ margin-bottom: 1pc;
+ }
+
+ h1.title { font-size: 140% }
+ h2.title { font-size: 140% }
+ h3.title { font-size: 130% }
+ h4.title { font-size: 120% }
+ h5.title { font-size: 110% }
+ h6.title { font-size: 100% }
+
+ .section h1
+ {
+ margin: 0em 0em 0.5em 0em;
+ font-size: 140%;
+ }
+
+ .section h2 { font-size: 140% }
+ .section h3 { font-size: 130% }
+ .section h4 { font-size: 120% }
+ .section h5 { font-size: 110% }
+ .section h6 { font-size: 100% }
+
+ /* Code on titles */
+ h1 tt.computeroutput { font-size: 140% }
+ h2 tt.computeroutput { font-size: 140% }
+ h3 tt.computeroutput { font-size: 130% }
+ h4 tt.computeroutput { font-size: 120% }
+ h5 tt.computeroutput { font-size: 110% }
+ h6 tt.computeroutput { font-size: 100% }
+
+
+ h3.author
+ {
+ font-size: 100%
+ }
+
+ h1 a, h2 a, h3 a, h4 a, h5 a, h6 a,
+ h1 a:hover, h2 a:hover, h3 a:hover, h4 a:hover, h5 a:hover, h6 a:hover,
+ h1 a:visited, h2 a:visited, h3 a:visited, h4 a:visited, h5 a:visited, h6 a:visited
+ {
+ text-decoration: none; /* no underline */
+ color: #000000;
+ border: none;
+ }
+
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/caution.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/important.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/note.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/caution.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/important.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/note.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/tip.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/solid/warning.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/tip.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/admonitions/warning.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/bottom-left.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/bottom-right.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/bottom.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/bottom-left.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/bottom-right.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/bottom.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/top-left.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/top-right.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/solid/top.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/top-left.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/top-right.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/box_wrapper/top.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/1.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/10.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/11.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/12.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/13.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/14.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/15.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/2.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/3.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/4.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/5.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/6.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/7.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/8.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/callouts/9.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/footer/background-left.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/footer/background-right.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/footer/background.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/header/background-more.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/header/background.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/header/flourish.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/navigation/home.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/navigation/next.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/navigation/prev.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/navigation/up.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/bc.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/cw.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/em.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/evening.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/kd.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/morning.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/sc.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/bc.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/cw.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/em.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/evening.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/kd.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/morning.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/sc.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/vim.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/solid/vs.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/vim.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/images/syntax/vs.png
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/html/lists.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/lists.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,85 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Lists
+-----------------------------------------------------------------------------*/
+
+
+ li
+ {
+ font-size: 10pt;
+ line-height: 1.3;
+ }
+
+ /* Unordered lists */
+ ul
+ {
+ text-align: left;
+ }
+
+ /* Ordered lists */
+ ol
+ {
+ text-align: left;
+ }
+
+ .ol_1 { list-style-type: decimal; }
+ .ol_a { list-style-type: lower-alpha; }
+ .ol_i { list-style-type: lower-roman; }
+ .ol_A { list-style-type: upper-alpha; }
+ .ol_I { list-style-type: upper-roman; }
+
+ /* Make the terms in definition lists bold */
+ .variablelist dl dt,
+ .term
+ {
+ font-weight: bold;
+ font-size: 10pt;
+ }
+
+ .variablelist table tbody tr td
+ {
+ text-align: left;
+ vertical-align: top;
+ padding: 0em 2em 0em 0em;
+ font-size: 10pt;
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1.3;
+ }
+
+ /* Make the terms in definition lists bold */
+ .variablelist dl dt
+ {
+ margin-bottom: 0.2em;
+ }
+
+ .variablelist dl dd
+ {
+ margin: 0em 0em 0.5em 2em;
+ font-size: 10pt;
+ }
+
+ .variablelist table tbody tr td p
+ .variablelist dl dd p
+ {
+ margin: 0em 0em 0.5em 0em;
+ line-height: 1;
+ }
+
+
Added: sandbox/libpoet/trunk/doc/style/html/main.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/main.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,75 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+ @import url(general.css);
+
+ @import url(header.css);
+
+ @import url(footer.css);
+
+ @import url(spirit_nav.css);
+
+ @import url(headings.css);
+
+ @import url(box_wrapper.css);
+
+ @import url(toc.css);
+
+ @import url(table.css);
+
+ @import url(lists.css);
+
+ @import url(blurbs.css);
+
+ @import url(programlisting.css);
+
+ @import url(callouts.css);
+
+ @import url(syntax/vs.css);
+
+ @import url(custom.css);
+
+/*----------------------------------------------------------------------------
+ Overwrite some style elements for print
+ (this may be moved inside each individual css)
+-----------------------------------------------------------------------------*/
+
+ @media print
+ {
+ /* Links */
+ a
+ {
+ color: black;
+ }
+
+ a:visited
+ {
+ color: black;
+ }
+
+ .spirit-nav
+ {
+ display: none;
+ }
+
+ /* Misc */
+ span.highlight
+ {
+ font-weight: bold;
+ }
+ }
Added: sandbox/libpoet/trunk/doc/style/html/nested_links.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/nested_links.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,66 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Grouped Links
+-----------------------------------------------------------------------------*/
+
+
+ div.nested-links-select-box
+ {
+ display: inline;
+ }
+
+ select.nested-links
+ {
+ background-color: #BEDEBA;
+ font-weight: bold;
+ font-size: 12px;
+ color: #006D00;
+ border: 1px solid #DCDCDC;
+ border-bottom: 1px solid #9D9D9D;
+ border-right: 1px solid #9D9D9D;
+ padding-bottom: 1px;
+ padding-right: 1px;
+ }
+
+ option.nested-links-title
+ {
+ background-color: #BEDEBA;
+ font-weight: bold;
+ font-size: 12px;
+ color: #006D00;
+ }
+
+ option.nested-links-first
+ {
+ background-color: #008000;
+ font-weight: bold;
+ font-size: 12px;
+ color: white;
+ }
+
+ option.nested-links-second
+ {
+ background-color: #FAFFFB;
+ padding: 0px 0px 0px 12px;
+ color: #006D00;
+ font-weight: normal;
+ }
+
Added: sandbox/libpoet/trunk/doc/style/html/programlisting.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/programlisting.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,186 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Program Listing
+-----------------------------------------------------------------------------*/
+
+
+ p tt.computeroutput
+ {
+ font-size: 10pt;
+ }
+
+ .synopsis
+ {
+ font-size: 10pt;
+ margin: 1pc 4% 0pc 4%;
+ }
+
+ .programlisting,
+ .screen
+ {
+ font-size: 10pt;
+ display: block;
+ margin: 1pc 4% 0pc 4%;
+ }
+
+ .synopsis .box-inner-wrapper,
+ .programlisting .box-inner-wrapper,
+ .screen .box-inner-wrapper
+ {
+ padding-left: 30px;
+ }
+
+
+ .style-switcher-box
+ {
+ margin-top: -20px;
+ padding-right: 10px;
+ float: right;
+ overflow: hidden;
+ height: 30px;
+ }
+
+ .ss-options
+ {
+ padding-top: 40px;
+ }
+
+ .ss-options:hover
+ {
+ padding-top: 0px;
+ }
+
+ .ss-option-vs
+ {
+ float: left;
+ background: url(images/syntax/vs.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-kd
+ {
+ float: left;
+ background: url(images/syntax/kd.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-sc
+ {
+ float: left;
+ background: url(images/syntax/sc.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-cw
+ {
+ float: left;
+ background: url(images/syntax/cw.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-bc
+ {
+ float: left;
+ background: url(images/syntax/bc.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-em
+ {
+ float: left;
+ background: url(images/syntax/em.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-vim
+ {
+ float: left;
+ background: url(images/syntax/vim.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-evening
+ {
+ float: left;
+ background: url(images/syntax/evening.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .ss-option-morning
+ {
+ float: left;
+ background: url(images/syntax/morning.png) no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+
+ * html body .ss-options
+ {
+ padding-top: 0px;
+ }
+
+ * html body .ss-option-vs
+ {
+ background: url(images/syntax/solid/vs.png) no-repeat center;
+ }
+
+ * html body .ss-option-kd
+ {
+ background: url(images/syntax/solid/kd.png) no-repeat center;
+ }
+
+ * html body .ss-option-sc
+ {
+ background: url(images/syntax/solid/sc.png) no-repeat center;
+ }
+
+ * html body .ss-option-cw
+ {
+ background: url(images/syntax/solid/cw.png) no-repeat center;
+ }
+
+ * html body .ss-option-em
+ {
+ background: url(images/syntax/solid/em.png) no-repeat center;
+ }
+
+ * html body .ss-option-bc
+ {
+ background: url(images/syntax/solid/bc.png) no-repeat center;
+ }
+
+ * html body .ss-option-vim
+ {
+ background: url(images/syntax/solid/vim.png) no-repeat center;
+ }
+
+ * html body .ss-option-evening
+ {
+ background: url(images/syntax/solid/evening.png) no-repeat center;
+ }
+ * html body .ss-option-morning
+ {
+ background: url(images/syntax/solid/morning.png) no-repeat center;
+ }
+
+
+
+
Added: sandbox/libpoet/trunk/doc/style/html/spirit_nav.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/spirit_nav.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,63 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Spirit Navigation
+-----------------------------------------------------------------------------*/
+
+
+ .spirit-nav
+ {
+ margin: 16px;
+ float: right;
+ }
+
+ .spirit-nav-icon
+ {
+ float: left;
+ margin-bottom: 10px;
+ }
+
+ .prev-icon
+ {
+ background: url(images/navigation/prev.png)
+ no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .next-icon
+ {
+ background: url(images/navigation/next.png)
+ no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .up-icon
+ {
+ background: url(images/navigation/up.png)
+ no-repeat center;
+ height: 30px; width: 30px;
+ }
+
+ .home-icon
+ {
+ background: url(images/navigation/home.png)
+ no-repeat center;
+ height: 30px; width: 30px;
+ }
Added: sandbox/libpoet/trunk/doc/style/html/syntax.xml
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax.xml 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8"?>
+<styleList>
+
+ <base href="syntax" />
+
+ <style title="vs" href="vs.css" preferred="true" />
+ <style title="kd" href="kd.css" />
+ <style title="em" href="em.css" />
+ <style title="cw" href="cw.css" />
+ <style title="bc" href="bc.css" />
+ <style title="sc" href="sc.css" />
+ <style title="vim" href="vim.css" />
+ <style title="morning" href="morning.css" />
+ <style title="evening" href="evening.css" />
+
+</styleList>
Added: sandbox/libpoet/trunk/doc/style/html/syntax/bc.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/bc.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,37 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Borland Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+
+ .keyword { color: #0F208E; font-weight: bold; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #2A7DC6; }
+ .char { color: #0F208E; }
+ .comment { color: #038302; }
+ .string { color: #0F208E; }
+ .number { color: #0F208E; }
+ .white_bkd { background-color: #E8FBE9; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
+
+
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/cw.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/cw.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,34 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Code Warrior Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+
+ .keyword { color: #0000B3; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #0000B3; }
+ .char { color: #666666; }
+ .comment { color: #B30000; }
+ .string { color: #666666; }
+ .number { color: #000000; }
+ .white_bkd { background-color: #E8FBE9; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/em.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/em.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,34 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Emacs Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+
+ .keyword { color: #8B0000; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #0000CD; }
+ .char { color: #008B00; }
+ .comment { color: #00008B; }
+ .string { color: #008B00; }
+ .number { color: #000000; }
+ .white_bkd { background-color: #E8FBE9; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/evening.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/evening.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,45 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Vim Evening Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+ .keyword { color: #60ff60; font-weight: bold; }
+ .identifier { color: #FFFFFF; font-weight: bold; }
+ .special-keyword{ color: #FFFF60; font-weight: bold; }
+ .special { color: #FFFFFF; }
+ .preprocessor { color: #FF80FF; }
+ .comment { color: #80A0FF; }
+ .string { color: #FFA0A0; background-color: #000000;}
+ .char { color: #FFA0A0; background-color: #000000;}
+ .number { color: #FFA0A0; background-color: #000000;}
+ .white_bkd { background-color: #333333; }
+ .dk_grey_bkd { background-color: #333333; }
+
+ .box-inner-wrapper { background-color: #333333;}
+ .box-outer-wrapper { background-color: #333333;}
+ .box-bottom-left { background-color: #333333;}
+ .box-bottom { background-color: #333333;}
+ .box-bottom-right { background-color: #333333;}
+ .box-top-right { background-color: #333333;}
+ .box-top-left { background-color: #333333;}
+ .box-top { background-color: #333333;}
+ .style-switcher-box { background-color: #333333;}
+
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/kd.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/kd.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,34 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ KDevelop Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+
+ .keyword { color: #000000; font-weight: bold; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #008000; }
+ .char { color: #FF00FF; }
+ .comment { color: #808080; font-style: italic; }
+ .string { color: #DD0000; }
+ .number { color: #0000FF; }
+ .white_bkd { background-color: #E8FBE9; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/morning.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/morning.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,44 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+/*----------------------------------------------------------------------------
+ Vim Morning Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+ .keyword { color: #2e8b57; font-weight: bold }
+ .special-keyword{ color: #A52A2A; font-weight: bold }
+ .special { color: #000000; }
+ .identifier { color: #000000; }
+ .preprocessor { color: #A020F0; }
+ .comment { color: #0000FF; }
+ .char { color: #FF00FF; background-color: #f2f2f2;}
+ .string { color: #FF00FF; background-color: #f2f2f2; }
+ .number { color: #FF00FF; background-color: #f2f2f2;}
+ .white_bkd { background-color: #E5E5E5; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
+ .box-inner-wrapper { background-color: #E5E5E5;}
+ .box-outer-wrapper { background-color: #E5E5E5;}
+ .box-bottom-left { background-color: #E5E5E5;}
+ .box-bottom { background-color: #E5E5E5;}
+ .box-bottom-right { background-color: #E5E5E5;}
+ .box-top-right { background-color: #E5E5E5;}
+ .box-top-left { background-color: #E5E5E5;}
+ .box-top { background-color: #E5E5E5;}
+ .style-switcher-box { background-color: #E5E5E5;}
+
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/sc.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/sc.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,36 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ SciTE Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+
+ .keyword { color: #3300CC; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #009999; }
+ .char { color: teal; }
+ .comment { color: #009900; }
+ .string { color: teal; }
+ .number { color: teal; }
+ .white_bkd { background-color: #E8FBE9; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
+
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/vim.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/vim.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,35 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Vim Default Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+ .keyword { color: #2E8B57; font-weight: bold }
+ .special-keyword{ color: #A52A2A; font-weight: bold }
+ .special { color: #000000; }
+ .identifier { color: #000000; }
+ .preprocessor { color: #A020F0; }
+ .comment { color: #0000FF; }
+ .char { color: #FF00FF; background-color: #fFffff;}
+ .string { color: #FF00FF; background-color: #fFffff; }
+ .number { color: #FF00FF; background-color: #fFffff;}
+ .white_bkd { background-color: #FFFFFF; }
+ .dk_grey_bkd { background-color: #999999; }
+
+
Added: sandbox/libpoet/trunk/doc/style/html/syntax/vs.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/syntax/vs.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,34 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Visual Studio Syntax Highlighting
+-----------------------------------------------------------------------------*/
+
+ .keyword { color: #0000FF; }
+ .identifier { color: #000000; }
+ .special { color: #707070; }
+ .preprocessor { color: #0000FF; }
+ .char { color: #A31515; }
+ .comment { color: #008000; }
+ .string { color: #A31515; }
+ .number { color: #000000; }
+ .white_bkd { background-color: #E8FBE9; }
+ .dk_grey_bkd { background-color: #A0DAAC; }
+
+
Added: sandbox/libpoet/trunk/doc/style/html/table.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/table.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,100 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Table
+-----------------------------------------------------------------------------*/
+
+
+ .table-title,
+ .table p .title
+ {
+ margin-left: 4%;
+ padding-right: 0.5em;
+ padding-left: 0.5em;
+ margin-top: 25px;
+ }
+
+ .table table,
+ .informaltable table
+ {
+ width: 92%;
+ margin-left: 4%;
+ margin-right: 4%;
+ }
+
+ /* Table Cells */
+
+ .table table tr th,
+ .informaltable table tr th
+ {
+ margin: 2px;
+ margin-bottom: 8px;
+ padding: 0.5em;
+ padding-top: 10px;
+ padding-bottom: 0px;
+ background-color: #F8F8F8;
+ border: 1px solid #ECECEC;
+ }
+
+ .table table tr th p,
+ .informaltable table tr th p
+ {
+ font-size: 10pt;
+ text-align: center;
+ line-height: 1.2;
+ margin: 0;
+ padding: 0;
+ padding-bottom: 10px;
+ }
+
+ .table table tr td,
+ .informaltable table tr td
+ {
+ margin: 2px;
+ padding: 0.5em;
+ padding-top: 10px;
+ padding-bottom: 0px;
+ background-color: white;
+ border: 1px solid #ECECEC;
+ font-size: 10pt;
+ }
+
+ .table table tr td p,
+ .informaltable table tr td p
+ {
+ text-align: left;
+ font-size: 10pt;
+ line-height: 1.2;
+ margin: 0;
+ padding: 0;
+ padding-bottom: 10px;
+ }
+
+ .table table:hover tr th,
+ .informaltable table:hover tr th
+ {
+ background-color: #E3F9E4;
+ }
+
+ .table table:hover tr td,
+ .informaltable table:hover tr td
+ {
+ background-color: #FAFFFB;
+ }
+
Added: sandbox/libpoet/trunk/doc/style/html/toc.css
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/doc/style/html/toc.css 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,34 @@
+/*=============================================================================
+
+ Boostbook Green Style
+
+ Copyright (c) 2006-2007 Matias Capeletto
+
+ Use, modification and distribution is subject to 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)
+
+ Acknowledgments:
+ This css is based on ideas from stylesheets from Joel De Guzman and
+ Rene Rivera.
+
+=============================================================================*/
+
+
+
+/*----------------------------------------------------------------------------
+ Table of contents
+-----------------------------------------------------------------------------*/
+
+
+ .toc
+ {
+ margin: 1pc 4% 0pc 4%;
+ font-size: 10pt;
+ line-height: 1.15;
+ }
+
+ div.toc div.box-inner-wrapper
+ {
+ padding-left: 36px;
+ }
\ No newline at end of file
Added: sandbox/libpoet/trunk/doc/style/pdf/images/DangerGeneral.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/caution.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/home.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/important.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/next.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/note.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/prev.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/tip.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/tip2.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/up.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/doc/style/pdf/images/warning.svg
==============================================================================
Binary file. No diff available.
Added: sandbox/libpoet/trunk/examples/active_object_example.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/examples/active_object_example.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,77 @@
+// An toy example showing how a full active object class can be defined
+// from a servant class, a scheduler, and active_functions.
+// The active_functions all share the same scheduler, so the
+// methods of the servant class are only called by a single
+// scheduler thread.
+
+// Copyright (C) Frank Mori Hess 2007-2008
+// 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 <boost/shared_ptr.hpp>
+#include <poet/active_function.hpp>
+#include <iostream>
+
+// servant class
+template <typename T>
+class passive_value
+{
+public:
+ passive_value(const T& initial_value): _value(initial_value)
+ {}
+ const T& add(const T& x)
+ {
+ _value += x;
+ return _value;
+ }
+ const T& multiply(const T& x)
+ {
+ _value *= x;
+ return _value;
+ }
+ const T& get() const
+ {
+ return _value;
+ }
+private:
+ T _value;
+};
+
+// active object class
+template <typename T>
+class active_value
+{
+private:
+ boost::shared_ptr<passive_value<T> > _servant;
+ boost::shared_ptr<poet::scheduler> _scheduler;
+public:
+ typedef typename poet::active_function<T (T)> add_type;
+ typedef typename poet::active_function<T (T)> multiply_type;
+ typedef typename poet::active_function<T ()> get_type;
+
+ active_value(const T& initial_value):
+ _servant(new passive_value<T>(initial_value)),
+ _scheduler(new poet::scheduler),
+ add(typename add_type::passive_slot_type(&passive_value<T>::add, _servant, _1),
+ _scheduler),
+ multiply(typename multiply_type::passive_slot_type(&passive_value<T>::multiply, _servant, _1),
+ _scheduler),
+ get(typename get_type::passive_slot_type(&passive_value<T>::get, _servant),
+ _scheduler)
+ {}
+ add_type add;
+ multiply_type multiply;
+ get_type get;
+};
+
+int main()
+{
+ active_value<int> my_active_object(1);
+ std::cout << "initial value is " << my_active_object.get().get() << std::endl;
+
+ my_active_object.add(10);
+ std::cout << "adding 10 and multiplying by 2 gives " << my_active_object.multiply(2).get() << std::endl;
+
+ return 0;
+}
Added: sandbox/libpoet/trunk/examples/acyclic_mutex_demo.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/examples/acyclic_mutex_demo.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,57 @@
+// An example of using ayclic_mutex to debug mutex
+// locking order violations.
+
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/thread/locks.hpp>
+#include <cstdlib>
+#include <poet/acyclic_mutex.hpp>
+#include <iostream>
+
+typedef poet::acyclic_mutex<boost::mutex> mutex_type;
+
+/* dumps mutexes locked by current thread to stderr, and
+a graphviz file to stdout. */
+void cycle_handler()
+{
+ poet::mutex_grapher::unique_lock grapher;
+ std::cerr << "Detected cycle in locking order graph.\n"
+ << "Currently locked mutexes:";
+ poet::mutex_grapher::mutex_list_type::const_iterator it;
+ for(it = grapher->locked_mutexes().begin();
+ it != grapher->locked_mutexes().end(); ++it)
+ {
+ std::cerr << "\n\tname = \"" << grapher->graph()[(*it)->vertex().get()].name << "\"";
+ }
+ std::cerr << std::endl;
+ grapher->write_graphviz(std::cout);
+ exit(1);
+}
+
+int main()
+{
+ // replace the default cycle handler (which aborts the program)
+ {
+ poet::mutex_grapher::unique_lock grapher;
+ grapher->set_cycle_handler(&cycle_handler);
+ }
+
+ mutex_type mutex_a("a");
+ mutex_type mutex_b("b");
+ mutex_type mutex_x;
+ {
+ boost::unique_lock<mutex_type> lock_a(mutex_a);
+ boost::unique_lock<mutex_type> lock_x(mutex_x);
+ }
+ {
+ boost::unique_lock<mutex_type> lock_x(mutex_x);
+ boost::unique_lock<mutex_type> lock_b(mutex_b);
+ /* this will violate the locking order we have established,
+ and will result in the cycle handler being called */
+ boost::unique_lock<mutex_type> lock_a(mutex_a);
+ }
+ return 0;
+}
Added: sandbox/libpoet/trunk/examples/monitor_demo.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/examples/monitor_demo.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,78 @@
+// An example of using the monitor_ptr and monitor classes
+// for automatically locked access to an object and waiting
+// on the monitor's condition variable.
+
+// Copyright (C) Frank Mori Hess 2007-2008
+// 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 <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <iostream>
+#include <poet/monitor.hpp>
+#include <poet/monitor_ptr.hpp>
+#include <poet/monitor_base.hpp>
+
+
+class Monitored: public poet::monitor_base
+{
+public:
+ Monitored(): _state(0)
+ {}
+ void wait_for_state(int state)
+ {
+ std::cerr << "thread " << boost::this_thread::get_id() << ": " <<
+ __FUNCTION__ << ": waiting for state = " << state << std::endl;
+ while(_state != state) wait();
+ std::cerr << "thread " << boost::this_thread::get_id() << ": " <<
+ __FUNCTION__ << ": have state = " << state << std::endl;
+ }
+ void set_state(int state)
+ {
+ std::cerr << "thread " << boost::this_thread::get_id() << ": " <<
+ __FUNCTION__ << ": state = " << state << std::endl;
+ _state = state;
+ notify_all();
+ }
+private:
+ int _state;
+};
+
+//example of using poet::monitor_ptr
+
+typedef poet::monitor_ptr<Monitored> monitor_ptr_type;
+
+void monitor_ptr_thread0_function(monitor_ptr_type mymonitor)
+{
+ poet::monitor_unique_lock<monitor_ptr_type> mon_lock(mymonitor);
+ mon_lock->set_state(1);
+ mon_lock->wait_for_state(2);
+ mon_lock->set_state(3);
+ mon_lock->wait_for_state(4);
+}
+
+void monitor_ptr_thread1_function(monitor_ptr_type mymonitor)
+{
+ mymonitor->wait_for_state(1);
+ {
+ poet::monitor_unique_lock<monitor_ptr_type> mon_lock(mymonitor);
+ mon_lock->set_state(2);
+ mon_lock->wait_for_state(3);
+ }
+ mymonitor->set_state(4);
+}
+
+int main()
+{
+ typedef poet::monitor<Monitored> monitor_type;
+ monitor_type mymonitor;
+ boost::thread thread0(boost::bind(&monitor_ptr_thread0_function, mymonitor.get_monitor_ptr()));
+ boost::thread thread1(boost::bind(&monitor_ptr_thread1_function, mymonitor.get_monitor_ptr()));
+ thread0.join();
+ thread1.join();
+
+ return 0;
+}
Added: sandbox/libpoet/trunk/examples/pipeline.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/examples/pipeline.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,77 @@
+// A toy example that calculates the length of a series of
+// 2 dimensional vectors concurrently using 4 threads.
+// A real program more concerned with performance
+// would perform less trivial operations in the active_functions,
+// to reduce the active_function calling overhead.
+
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/array.hpp>
+#include <cmath>
+#include <functional>
+#include <iostream>
+#include <poet/active_function.hpp>
+#include <vector>
+
+double square_root(double a)
+{
+ return std::sqrt(a);
+}
+
+int main()
+{
+ static const unsigned num_vectors = 10;
+ unsigned i;
+
+ // input data, assigned actual values later
+ std::vector<boost::array<poet::promise<double>, 2> > promises;
+ // we push the promises on onto the std::vector one at a time to make
+ // sure the std::vector doesn't copy-construct them from each other.
+ for(i = 0; i < num_vectors; ++i)
+ {
+ promises.push_back(boost::array<poet::promise<double>, 2>());
+ }
+
+ // active_functions
+ poet::active_function<double (double, double)> active_adder((std::plus<double>()));
+ poet::active_function<double (double, double)> active_multiplier0((std::multiplies<double>()));
+ poet::active_function<double (double, double)> active_multiplier1((std::multiplies<double>()));
+ poet::active_function<double (double)> active_sqrt(&square_root);
+
+ std::vector<poet::future<double> > lengths;
+ // pass promises through our active_function pipeline
+ for(i = 0; i < promises.size(); ++i)
+ {
+ poet::future<double> product0 = active_multiplier0(promises.at(i).at(0), promises.at(i).at(0));
+ poet::future<double> product1 = active_multiplier1(promises.at(i).at(1), promises.at(i).at(1));
+
+ poet::future<double> sum = active_adder(product0, product1);
+
+ poet::future<double> root = active_sqrt(sum);
+
+ lengths.push_back(root);
+ }
+
+ // fulfill input promises
+ for(i = 0; i < promises.size(); ++i)
+ {
+ promises.at(i).at(0).fulfill(i % 4);
+ promises.at(i).at(1).fulfill(i % 3);
+ }
+
+ // wait for futures to become ready and convert them to values
+ for(i = 0; i < lengths.size(); ++i)
+ {
+ boost::array<poet::future<double>, 2> vec;
+ vec.at(0) = promises.at(i).at(0);
+ vec.at(1) = promises.at(i).at(1);
+ double value = lengths.at(i);
+ std::cout << "vector " << i << " = {" << vec.at(0) << ", " <<
+ vec.at(1) << "}, length = " << value << "\n";
+ }
+
+ return 0;
+}
Added: sandbox/libpoet/trunk/examples/transform.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/examples/transform.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,57 @@
+// An example which passes an active_function as the functor
+// used by std::transform, in order to perform a transformation
+// on containers of futures.
+
+// Copyright (C) Frank Mori Hess 2008
+// 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 <cmath>
+#include <functional>
+#include <iostream>
+#include <poet/active_function.hpp>
+#include <vector>
+
+int main()
+{
+ unsigned i;
+ const unsigned vector_length = 10;
+ // input data, assigned actual values later
+ std::vector<poet::promise<double> > x_promises;
+ std::vector<poet::promise<double> > y_promises;
+ // we push the promises on onto the std::vector one at a time to make
+ // sure the std::vector doesn't copy-construct them from each other.
+ for(i = 0; i < vector_length; ++i)
+ {
+ x_promises.push_back(poet::promise<double>());
+ y_promises.push_back(poet::promise<double>());
+ }
+
+ // active_functions
+ std::plus<double> passive_adder;
+ poet::active_function<double (double, double)> active_adder(passive_adder);
+
+ std::vector<poet::future<double> > x;
+ std::copy(x_promises.begin(), x_promises.end(), std::back_inserter(x));
+ std::vector<poet::future<double> > y;
+ std::copy(y_promises.begin(), y_promises.end(), std::back_inserter(y));
+ std::vector<poet::future<double> > sum;
+
+ std::transform(x.begin(), x.end(), y.begin(), std::back_inserter(sum), active_adder);
+
+ // fulfill input promises
+ for(i = 0; i < x_promises.size(); ++i)
+ {
+ x_promises.at(i).fulfill(i % 4);
+ y_promises.at(i).fulfill(i % 3);
+ }
+
+ // wait for futures to become ready and convert them to values
+ for(i = 0; i < sum.size(); ++i)
+ {
+ std::cout << "sum " << i << " = " << sum.at(i).get() << "\n";
+ }
+
+ return 0;
+}
Added: sandbox/libpoet/trunk/make_release.sh
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/make_release.sh 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,17 @@
+#!/bin/bash
+
+set -o errexit
+
+TOP_DIR=$(pwd)
+TOP_DIST_DIR=$TOP_DIR/test/libpoet-$(date +%F)
+
+cd test
+cvs export -rHEAD libpoet
+mv libpoet $TOP_DIST_DIR
+cd $TOP_DIST_DIR/doc
+cp -a $TOP_DIR/doc/style .
+cp -a $TOP_DIR/doc/javascript .
+cd boostbook
+make
+cd $TOP_DIST_DIR/..
+tar -czf $TOP_DIST_DIR.tgz $(basename $TOP_DIST_DIR) --owner=0 --group=0
Added: sandbox/libpoet/trunk/poet/active_function.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/active_function.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,57 @@
+/*
+ A template class designed to make it easier to produce
+ active objects and asynchronous objects.
+
+ Author: Frank Hess <frank.hess_at_[hidden]>
+ Begin: 2007-01-23
+*/
+
+// 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 _POET_ACTIVE_FUNCTION_HPP
+#define _POET_ACTIVE_FUNCTION_HPP
+
+#include <boost/preprocessor/arithmetic.hpp>
+#include <boost/preprocessor/cat.hpp>
+#include <boost/preprocessor/iteration.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signals2/slot.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/type_traits.hpp>
+#include <boost/weak_ptr.hpp>
+#include <poet/active_object.hpp>
+#include <poet/future.hpp>
+#include <poet/future_barrier.hpp>
+#include <vector>
+
+#ifndef POET_ACTIVE_FUNCTION_MAX_ARGS
+#define POET_ACTIVE_FUNCTION_MAX_ARGS 10
+#endif
+
+#define BOOST_PP_ITERATION_LIMITS (0, POET_ACTIVE_FUNCTION_MAX_ARGS)
+#define BOOST_PP_FILENAME_1 <poet/detail/active_function_template.hpp>
+#include BOOST_PP_ITERATE()
+
+namespace poet
+{
+ template<typename Signature>
+ class active_function: public detail::active_functionN<boost::function_traits<Signature>::arity, Signature>::type
+ {
+ private:
+ typedef typename detail::active_functionN<boost::function_traits<Signature>::arity, Signature>::type base_type;
+
+ public:
+ active_function()
+ {}
+ active_function(const typename base_type::passive_slot_type &passive_function,
+ boost::shared_ptr<scheduler_base> scheduler = boost::shared_ptr<scheduler_base>()):
+ base_type(passive_function, scheduler)
+ {}
+ virtual ~active_function() {}
+ };
+}
+
+#endif // _POET_ACTIVE_FUNCTION_HPP
Added: sandbox/libpoet/trunk/poet/active_object.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/active_object.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,172 @@
+/*
+ This header defines some classes that can be used to build
+ active objects. See the paper "Active Object, An Object
+ Behavioral Pattern for Concurrent Programming." by
+ R. Greg Lavender and Douglas C. Schmidt
+ for more information about active objects.
+
+ Active objects that use Futures for both input parameters and
+ return values can be chained together in pipelines or do
+ dataflow-like processing, thereby achieving good concurrency.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2007-01-22
+*/
+
+// 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 _POET_ACTIVE_OBJECT_H
+#define _POET_ACTIVE_OBJECT_H
+
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
+#include <boost/signals2/signal.hpp>
+#include <list>
+#include <poet/detail/condition.hpp>
+#include <poet/future.hpp>
+#include <poet/future_select.hpp>
+
+namespace poet
+{
+ class method_request_base
+ {
+ public:
+ method_request_base() {}
+ virtual ~method_request_base() {}
+ virtual void run() = 0;
+ virtual future<void> scheduling_guard() const = 0;
+ };
+
+ class activation_queue_base
+ {
+ public:
+ typedef unsigned long size_type;
+
+ virtual ~activation_queue_base() {}
+ virtual void push_back(const boost::shared_ptr<method_request_base> &request) = 0;
+ virtual boost::shared_ptr<method_request_base> get_request() = 0;
+ virtual size_type size() const = 0;
+ virtual bool empty() const = 0;
+ virtual void wake() = 0;
+ };
+
+ class in_order_activation_queue: public activation_queue_base
+ {
+ public:
+ virtual ~in_order_activation_queue() {}
+ inline virtual void push_back(const boost::shared_ptr<method_request_base> &request);
+ inline virtual boost::shared_ptr<method_request_base> get_request();
+ virtual size_type size() const
+ {
+ boost::mutex::scoped_lock lock(_mutex);
+ return _pendingRequests.size();
+ }
+ virtual bool empty() const
+ {
+ boost::mutex::scoped_lock lock(_mutex);
+ return _pendingRequests.empty();
+ }
+ inline virtual void wake();
+ private:
+ typedef std::deque<boost::shared_ptr<method_request_base> > request_container_type;
+
+ request_container_type _pendingRequests;
+ mutable boost::mutex _mutex;
+ promise<boost::shared_ptr<method_request_base> >_next_method_request;
+ promise<boost::shared_ptr<method_request_base> >_wake_promise;
+ };
+
+ class out_of_order_activation_queue: public activation_queue_base
+ {
+ typedef future_selector<boost::shared_ptr<method_request_base> > selector_type;
+ public:
+ out_of_order_activation_queue()
+ {}
+ virtual ~out_of_order_activation_queue() {}
+
+ inline virtual void push_back(const boost::shared_ptr<method_request_base> &request);
+ inline virtual boost::shared_ptr<method_request_base> get_request();
+ virtual size_type size() const
+ {
+ const selector_type::difference_type size = _selector.size();
+ BOOST_ASSERT(size >= 0);
+ return size;
+ }
+ virtual bool empty() const
+ {
+ BOOST_ASSERT(_selector.size() >= 0);
+ return _selector.size() == 0;
+ }
+ inline virtual void wake();
+ private:
+ mutable boost::mutex _mutex;
+ selector_type _selector;
+ promise<boost::shared_ptr<method_request_base> >_wake_promise;
+ };
+
+ class scheduler_base
+ {
+ public:
+ virtual ~scheduler_base()
+ {}
+ virtual void post_method_request(const boost::shared_ptr<method_request_base> &methodRequest) = 0;
+ virtual void kill() = 0;
+ virtual void join() = 0;
+ };
+
+ namespace detail
+ {
+ class scheduler_impl
+ {
+ public:
+ inline scheduler_impl(const boost::shared_ptr<activation_queue_base> &activationQueue);
+ ~scheduler_impl() {}
+ inline void post_method_request(const boost::shared_ptr<method_request_base> &methodRequest);
+ inline void kill();
+ inline void detach();
+ inline bool mortallyWounded() const;
+ static inline void dispatcherThreadFunction(const boost::shared_ptr<scheduler_impl> &shared_this);
+ private:
+ inline bool dispatch();
+ bool detached() const
+ {
+ return _detached;
+ }
+
+ boost::shared_ptr<activation_queue_base> _activationQueue;
+ poet::promise<boost::shared_ptr<method_request_base> > _wake_promise;
+ mutable boost::mutex _mutex;
+ bool _mortallyWounded;
+ bool _detached;
+ };
+ }
+
+ class scheduler: public scheduler_base
+ {
+ public:
+ inline scheduler(const boost::shared_ptr<activation_queue_base> &activationQueue =
+ boost::shared_ptr<activation_queue_base>(new out_of_order_activation_queue));
+ virtual ~scheduler()
+ {
+ _pimpl->detach();
+ }
+ virtual void post_method_request(const boost::shared_ptr<method_request_base> &methodRequest)
+ {
+ _pimpl->post_method_request(methodRequest);
+ }
+ virtual void kill()
+ {
+ _pimpl->kill();
+ }
+ inline virtual void join();
+ private:
+ boost::shared_ptr<detail::scheduler_impl> _pimpl;
+ boost::shared_ptr<boost::thread> _dispatcherThread;
+ };
+}
+
+#include <poet/detail/active_object.cpp>
+
+#endif // _POET_ACTIVE_OBJECT_H
Added: sandbox/libpoet/trunk/poet/acyclic_mutex.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/acyclic_mutex.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,441 @@
+/*
+ A mutex wrapper which automatically tracks locking order to insure no deadlocks
+ are possible.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-10-26
+*/
+
+// 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 _POET_ACYCLIC_MUTEX_HPP
+#define _POET_ACYCLIC_MUTEX_HPP
+
+#include <boost/graph/graphviz.hpp>
+#include <boost/optional.hpp>
+#include <boost/thread/locks.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/tss.hpp>
+#include <cassert>
+#include <functional>
+#include <poet/acyclic_mutex_base.hpp>
+#include <poet/mutex_grapher.hpp>
+#include <poet/mutex_properties.hpp>
+#include <sstream>
+#include <string>
+
+namespace poet
+{
+ namespace detail
+ {
+ template<int initial_value = 0>
+ class thread_specific_count
+ {
+ public:
+ thread_specific_count()
+ {}
+ int& get()
+ {
+ check_lock_count_init();
+ return *_lock_count;
+ }
+ const int& get() const
+ {
+ check_lock_count_init();
+ return *_lock_count;
+ }
+ private:
+ void check_lock_count_init() const
+ {
+ if(_lock_count.get() == 0) _lock_count.reset(new int(initial_value));
+ }
+ mutable boost::thread_specific_ptr<int> _lock_count;
+ };
+
+ template<typename AcyclicMutex>
+ class acyclic_scoped_lock: public boost::unique_lock<AcyclicMutex>
+ {
+ public:
+ acyclic_scoped_lock(AcyclicMutex &mutex):
+ boost::unique_lock<AcyclicMutex>(mutex, boost::defer_lock_t())
+ {
+ this->lock();
+ }
+ acyclic_scoped_lock(AcyclicMutex &mutex, bool do_lock):
+ boost::unique_lock<AcyclicMutex>(mutex, boost::defer_lock_t())
+ {
+ if(do_lock)
+ {
+ this->lock();
+ }
+ }
+ bool locked() const {return this->owns_lock();}
+ };
+
+ template<typename AcyclicMutex>
+ class acyclic_scoped_try_lock: public acyclic_scoped_lock<AcyclicMutex>
+ {
+ typedef acyclic_scoped_lock<AcyclicMutex> base_class;
+ public:
+ acyclic_scoped_try_lock(AcyclicMutex &mutex): base_class(mutex, false)
+ {
+ this->try_lock();
+ }
+ acyclic_scoped_try_lock(AcyclicMutex &mutex, bool do_lock): base_class(mutex, do_lock)
+ {}
+ };
+
+ template<typename AcyclicMutex>
+ class acyclic_scoped_timed_lock: public acyclic_scoped_try_lock<AcyclicMutex>
+ {
+ typedef acyclic_scoped_try_lock<AcyclicMutex> base_class;
+ public:
+ template<typename Timeout>
+ acyclic_scoped_timed_lock(AcyclicMutex &mutex, const Timeout &t): base_class(mutex, false)
+ {
+ this->timed_lock(t);
+ }
+ acyclic_scoped_timed_lock(AcyclicMutex &mutex, bool do_lock): base_class(mutex, do_lock)
+ {}
+ };
+
+ template<typename Mutex, bool recursive, enum mutex_model model, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex;
+
+#ifdef ACYCLIC_MUTEX_NDEBUG // user is compiling with lock order debugging disabled
+ template<typename Mutex, bool recursive, enum mutex_model model, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex: public acyclic_mutex_base, public Mutex
+ {
+ public:
+ typedef Mutex mutex_type;
+ typedef Key key_type;
+ typedef KeyCompare key_compare;
+
+ specialized_acyclic_mutex()
+ {}
+ specialized_acyclic_mutex(const Key &node_key)
+ {}
+ boost::optional<Key> node_key() const {return boost::optional<Key>();}
+ };
+#else // ACYCLIC_MUTEX_NDEBUG undefined
+
+ // non-recursive mutex
+ template<typename Mutex, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex<Mutex, false, Lockable, Key, KeyCompare>:
+ public acyclic_mutex_base
+ {
+ public:
+ typedef Mutex mutex_type;
+ typedef Key key_type;
+ typedef KeyCompare key_compare;
+ typedef detail::acyclic_scoped_lock<specialized_acyclic_mutex> scoped_lock;
+ typedef detail::acyclic_scoped_try_lock<specialized_acyclic_mutex> scoped_try_lock;
+
+ specialized_acyclic_mutex()
+ {}
+ specialized_acyclic_mutex(const Key &node_key): _node_key(node_key)
+ {}
+
+ boost::optional<Key> node_key() const {return _node_key;}
+
+ // Boost.Threads interface for Lockable concepts
+ // Lockable
+ void lock()
+ {
+ track_lock();
+ _wrapped_mutex.lock();
+ }
+ bool try_lock()
+ {
+ track_lock();
+ bool successful = _wrapped_mutex.try_lock();
+ if(successful == false) track_unlock();
+ return successful;
+ }
+ void unlock()
+ {
+ _wrapped_mutex.unlock();
+ track_unlock();
+ }
+ protected:
+ boost::optional<Key> _node_key;
+ Mutex _wrapped_mutex;
+
+ void track_lock()
+ {
+ bool cycle_detected;
+ {
+ mutex_grapher::scoped_lock lock;
+ cycle_detected = lock->track_lock(*this);
+ };
+ /* _cycle_handler is run with no locks held by libpoet,
+ to minimize chance of deadlock with user-provided cycle handler.
+ tracking of locking events is disabled after the first cycle
+ is detected. */
+ if(cycle_detected) mutex_grapher::instance().direct()->_cycle_handler();
+ }
+ void track_unlock()
+ {
+ mutex_grapher::scoped_lock lock;
+ lock->track_unlock(*this);
+ }
+ };
+
+ // recursive mutex
+ template<typename Mutex, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex<Mutex, true, Lockable, Key, KeyCompare>:
+ public specialized_acyclic_mutex<Mutex, false, Lockable, Key, KeyCompare>
+ {
+ typedef specialized_acyclic_mutex<Mutex, false, Lockable, Key, KeyCompare> base_class;
+ public:
+ specialized_acyclic_mutex()
+ {}
+ specialized_acyclic_mutex(const Key &node_key): base_class(node_key)
+ {}
+ ~specialized_acyclic_mutex() {}
+
+ void lock()
+ {
+ track_lock();
+ this->_wrapped_mutex.lock();
+ }
+ bool try_lock()
+ {
+ track_lock();
+ bool successful = this->_wrapped_mutex.try_lock();
+ if(successful == false) track_unlock();
+ return successful;
+ }
+ void unlock()
+ {
+ this->_wrapped_mutex.unlock();
+ track_unlock();
+ }
+ private:
+ void increment_recursive_lock_count()
+ {
+ ++(_lock_count.get());
+ assert(_lock_count.get() >= 0);
+ }
+ void decrement_recursive_lock_count()
+ {
+ --(_lock_count.get());
+ assert(_lock_count.get() >= 0);
+ }
+ void track_lock()
+ {
+ if(_lock_count.get() == 0)
+ {
+ base_class::track_lock();
+ }
+ increment_recursive_lock_count();
+ }
+ void track_unlock()
+ {
+ decrement_recursive_lock_count();
+ if(_lock_count.get() == 0)
+ {
+ base_class::track_unlock();
+ }
+ }
+ detail::thread_specific_count<> _lock_count;
+ };
+
+ // timed mutex
+ template<typename Mutex, bool recursive, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex<Mutex, recursive, TimedLockable, Key, KeyCompare>:
+ public specialized_acyclic_mutex<Mutex, recursive, Lockable, Key, KeyCompare>
+ {
+ typedef specialized_acyclic_mutex<Mutex, recursive, Lockable, Key, KeyCompare> base_class;
+ public:
+ typedef detail::acyclic_scoped_timed_lock<specialized_acyclic_mutex> scoped_timed_lock;
+
+ specialized_acyclic_mutex()
+ {}
+ specialized_acyclic_mutex(const Key &node_key): base_class(node_key)
+ {}
+
+ // TimedLockable
+ template<typename Timeout>
+ bool timed_lock(const Timeout &timeout)
+ {
+ base_class::track_lock();
+ bool successful = this->_wrapped_mutex.try_lock(timeout);
+ if(successful == false) base_class::track_unlock();
+ return successful;
+ }
+ };
+
+ // SharedLockable
+ template<typename Mutex, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex<Mutex, false, SharedLockable, Key, KeyCompare>:
+ public specialized_acyclic_mutex<Mutex, false, Lockable, Key, KeyCompare>
+ {
+ typedef specialized_acyclic_mutex<Mutex, false, Lockable, Key, KeyCompare> base_class;
+ public:
+ specialized_acyclic_mutex()
+ {}
+ specialized_acyclic_mutex(const Key &node_key): base_class(node_key)
+ {}
+
+ // SharedLockable
+ void lock_shared()
+ {
+ track_lock_shared();
+ this->_wrapped_mutex.lock_shared();
+ }
+ bool try_lock_shared()
+ {
+ track_lock_shared();
+ bool successful = this->_wrapped_mutex.try_lock_shared();
+ if(successful == false) track_unlock_shared();
+ return successful;
+ }
+ template<typename Timeout>
+ bool timed_lock_shared(const Timeout &timeout)
+ {
+ track_lock_shared();
+ bool successful = this->_wrapped_mutex.timed_lock_shared(timeout);
+ if(successful == false) track_unlock_shared();
+ return successful;
+ }
+ void unlock_shared()
+ {
+ this->_wrapped_mutex.unlock_shared();
+ track_unlock_shared();
+ }
+ void unlock_and_lock_shared()
+ {
+ ++_shared_lock_count.get();
+ assert(_shared_lock_count.get() >= 0);
+ this->_wrapped_mutex.unlock_and_lock_shared();
+ }
+ protected:
+ void track_lock_shared()
+ {
+ if(_shared_lock_count.get() == 0)
+ {
+ base_class::track_lock();
+ }
+ ++_shared_lock_count.get();
+ assert(_shared_lock_count.get() >= 0);
+ }
+ void track_unlock_shared()
+ {
+ --_shared_lock_count.get();
+ assert(_shared_lock_count.get() >= 0);
+ if(_shared_lock_count.get() == 0)
+ {
+ base_class::track_unlock();
+ }
+ }
+ protected:
+ detail::thread_specific_count<0> _shared_lock_count;
+ };
+
+ // UpgradeLockable
+ template<typename Mutex, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex<Mutex, false, UpgradeLockable, Key, KeyCompare>:
+ public specialized_acyclic_mutex<Mutex, false, SharedLockable, Key, KeyCompare>
+ {
+ typedef specialized_acyclic_mutex<Mutex, false, SharedLockable, Key, KeyCompare> base_class;
+ public:
+ specialized_acyclic_mutex()
+ {}
+ specialized_acyclic_mutex(const Key &node_key): base_class(node_key)
+ {}
+
+ // UpgradeLockable
+ void lock_upgrade()
+ {
+ track_lock_upgrade();
+ this->_wrapped_mutex.lock_upgrade();
+ }
+ void unlock_upgrade()
+ {
+ this->_wrapped_mutex.unlock_upgrade();
+ track_unlock_upgrade();
+ }
+ void unlock_upgrade_and_lock()
+ {
+ if(safe_to_upgrade() == false)
+ {
+ // this should always cause a cycle to be detected
+ this->track_lock();
+ }
+ --_upgrade_lock_count.get();
+ assert(_upgrade_lock_count.get() >= 0);
+ --this->_shared_lock_count.get();
+ assert(this->_shared_lock_count.get() >= 0);
+ this->_wrapped_mutex.unlock_upgrade_and_lock();
+ }
+ void unlock_upgrade_and_lock_shared()
+ {
+ --_upgrade_lock_count.get();
+ assert(_upgrade_lock_count.get() >= 0);
+ this->_wrapped_mutex.unlock_upgrade_and_lock_shared();
+ }
+ void unlock_and_lock_upgrade()
+ {
+ ++_upgrade_lock_count.get();
+ assert(_upgrade_lock_count.get() == 1);
+ ++this->_shared_lock_count.get();
+ assert(this->_shared_lock_count.get() >= 0);
+ this->_wrapped_mutex.unlock_and_lock_upgrade();
+ }
+ private:
+ bool safe_to_upgrade() const
+ {
+ if(this->_shared_lock_count.get() != 1) return false;
+ mutex_grapher::scoped_lock lock;
+ // if this is the most recently locked mutex the current thread is holding,
+ // then it is okay to upgrade
+ return lock->locked_mutexes().back() == this;
+ }
+ void track_lock_upgrade()
+ {
+ if(_upgrade_lock_count.get() == 0)
+ {
+ base_class::track_lock_shared();
+ }else
+ {
+ // this should always cause a cycle to be detected
+ this->track_lock();
+ }
+ ++_upgrade_lock_count.get();
+ assert(_upgrade_lock_count.get() >= 0);
+ }
+ void track_unlock_upgrade()
+ {
+ --_upgrade_lock_count.get();
+ assert(_upgrade_lock_count.get() >= 0);
+ base_class::track_unlock_shared();
+ }
+
+ detail::thread_specific_count<0> _upgrade_lock_count;
+ };
+#endif // ACYCLIC_MUTEX_NDEBUG
+ };
+
+ template<typename Mutex = boost::mutex, typename Key = std::string, typename KeyCompare = std::less<Key> >
+ class acyclic_mutex:
+ public detail::specialized_acyclic_mutex<Mutex, mutex_properties<Mutex>::recursive,
+ mutex_properties<Mutex>::model, Key, KeyCompare>
+ {
+ typedef typename detail::specialized_acyclic_mutex<Mutex, mutex_properties<Mutex>::recursive,
+ mutex_properties<Mutex>::model, Key, KeyCompare> base_class;
+ public:
+ acyclic_mutex()
+ {}
+ acyclic_mutex(const Key &node_key): base_class(node_key)
+ {}
+ ~acyclic_mutex()
+ {
+ mutex_grapher::scoped_lock lock;
+ lock->release_vertex(*this);
+ }
+ };
+};
+
+#endif // _POET_ACYCLIC_MUTEX_HPP
Added: sandbox/libpoet/trunk/poet/acyclic_mutex_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/acyclic_mutex_base.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,92 @@
+/*
+ A mutex wrapper which automatically tracks locking order to insure no deadlocks
+ are possible.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-10-26
+*/
+
+// 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 _POET_ACYCLIC_MUTEX_BASE_HPP
+#define _POET_ACYCLIC_MUTEX_BASE_HPP
+
+#include <boost/optional.hpp>
+#include <boost/thread/mutex.hpp>
+#include <poet/detail/template_static.hpp>
+#include <poet/detail/mutex_grapher_decl.hpp>
+#include <sstream>
+#include <string>
+
+#ifdef NDEBUG
+#ifndef ACYCLIC_MUTEX_NDEBUG
+#define ACYCLIC_MUTEX_NDEBUG
+#endif // ACYCLIC_MUTEX_NDEBUG
+#endif // NDEBUG
+
+namespace poet
+{
+#ifdef ACYCLIC_MUTEX_NDEBUG
+ class acyclic_mutex_base
+ {
+ protected:
+ typedef mutex_grapher::locking_order_graph::vertex_descriptor vertex_descriptor_type;
+ public:
+ virtual ~acyclic_mutex_base() {}
+
+ boost::optional<vertex_descriptor_type> vertex() const {return boost::optional<vertex_descriptor_type>();}
+ protected:
+ friend class poet::mutex_grapher;
+
+ void set_vertex(vertex_descriptor_type vertex)
+ {}
+ virtual bool will_really_lock() const
+ {
+ return true;
+ }
+ virtual bool will_really_unlock() const
+ {
+ return true;
+ }
+ virtual void increment_recursive_lock_count()
+ {}
+ virtual void decrement_recursive_lock_count()
+ {}
+ };
+#else // ACYCLIC_MUTEX_NDEBUG not defined
+
+ class acyclic_mutex_base
+ {
+ protected:
+ typedef mutex_grapher::locking_order_graph::vertex_descriptor vertex_descriptor_type;
+ public:
+ virtual ~acyclic_mutex_base() {}
+
+ boost::optional<vertex_descriptor_type> vertex() const {return _vertex;}
+ protected:
+ friend class poet::mutex_grapher;
+
+ void set_vertex(vertex_descriptor_type vertex)
+ {
+ _vertex = vertex;
+ }
+ virtual bool will_really_lock() const
+ {
+ return true;
+ }
+ virtual bool will_really_unlock() const
+ {
+ return true;
+ }
+ virtual void increment_recursive_lock_count()
+ {}
+ virtual void decrement_recursive_lock_count()
+ {}
+
+ boost::optional<vertex_descriptor_type> _vertex;
+ };
+#endif // ACYCLIC_MUTEX_NDEBUG
+};
+
+#endif // _POET_ACYCLIC_MUTEX_BASE_HPP
Added: sandbox/libpoet/trunk/poet/detail/active_function_template.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/active_function_template.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,170 @@
+/*
+ Template for ActiveFunction1, ActiveFunction2, ... classes that implement
+ ActiveFunctions with signatures that have 1, 2, ... parameters
+
+ Author: Frank Hess <frank.hess_at_[hidden]>
+ Begin: 2007-01-26
+*/
+
+// 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)
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#include <poet/detail/preprocessor_macros.hpp>
+
+#define POET_ACTIVE_FUNCTION_NUM_ARGS BOOST_PP_ITERATION()
+
+#define POET_ACTIVE_FUNCTION_CLASS_NAME BOOST_PP_CAT(active_function, POET_ACTIVE_FUNCTION_NUM_ARGS)
+#define POET_AF_METHOD_REQUEST_CLASS_NAME BOOST_PP_CAT(active_function_method_request, POET_ACTIVE_FUNCTION_NUM_ARGS)
+
+// typename poet::future<boost::function_traits<Signature>::argn_type>
+#define POET_ACTIVE_FUNCTION_ARG_TYPE(z, n, Signature) \
+ poet::future< BOOST_PP_CAT(BOOST_PP_CAT(typename boost::function_traits<Signature>::arg, BOOST_PP_INC(n)), _type) >
+// poet::future<typename boost::function_traits<Signature>::argn_type> argn
+#define POET_ACTIVE_FUNCTION_FULL_ARG(z, n, Signature) \
+ POET_ACTIVE_FUNCTION_ARG_TYPE(~, n, Signature) POET_ARG_NAME(~, n, arg)
+// poet::future<typename boost::function_traits<Signature>::arg1_type> arg1,
+// poet::future<typename boost::function_traits<Signature>::arg2_type> arg2,
+// ...
+// poet::future<typename boost::function_traits<Signature>::argn_type> argn
+#define POET_ACTIVE_FUNCTION_FULL_ARGS(arity, Signature) \
+ BOOST_PP_ENUM(arity, POET_ACTIVE_FUNCTION_FULL_ARG, Signature)
+// typename poet::future<boost::function_traits<Signature>::argn_type> _argn ;
+#define POET_ACTIVE_FUNCTION_ARG_DECLARATION(z, n, Signature) POET_ACTIVE_FUNCTION_ARG_TYPE(~, n, Signature) \
+ POET_ARG_NAME(~, n, _arg) ;
+// tupleName.get < n >()
+#define POET_ACTIVE_FUNCTION_GET_TUPLE_ELEMENT(z, n, tupleName) \
+ tupleName.get< n >()
+
+namespace poet
+{
+ namespace detail
+ {
+ template <typename Signature>
+ class POET_AF_METHOD_REQUEST_CLASS_NAME:
+ public method_request_base
+ {
+ public:
+ typedef typename boost::function_traits<Signature>::result_type passive_result_type;
+ typedef method_request_base base_type;
+ typedef typename boost::signals2::slot<Signature> passive_slot_type;
+
+ POET_AF_METHOD_REQUEST_CLASS_NAME(const promise<passive_result_type> &returnValue,
+ POET_ACTIVE_FUNCTION_FULL_ARGS(POET_ACTIVE_FUNCTION_NUM_ARGS, Signature) BOOST_PP_COMMA_IF(POET_ACTIVE_FUNCTION_NUM_ARGS)
+ const boost::shared_ptr<boost::signals2::slot<Signature> > &passive_function): _return_value(returnValue),
+ POET_REPEATED_ARG_CONSTRUCTOR(POET_ACTIVE_FUNCTION_NUM_ARGS, arg) BOOST_PP_COMMA_IF(POET_ACTIVE_FUNCTION_NUM_ARGS)
+ _passive_function(passive_function)
+ {}
+ virtual ~POET_AF_METHOD_REQUEST_CLASS_NAME()
+ {}
+
+ virtual void run()
+ {
+ try
+ {
+ passive_result_type *resolver = 0;
+ m_run(resolver);
+ }
+ catch(...)
+ {
+ _return_value.renege(current_exception());
+ }
+ }
+ virtual future<void> scheduling_guard() const
+ {
+#if POET_ACTIVE_FUNCTION_NUM_ARGS == 0
+ future<int> ready_future = 1;
+ return ready_future;
+#elif POET_ACTIVE_FUNCTION_NUM_ARGS == 1
+ return _arg1;
+#else
+ return future_barrier(POET_REPEATED_ARG_NAMES(POET_ACTIVE_FUNCTION_NUM_ARGS, _arg));
+#endif
+ }
+ private:
+ void m_run(void *)
+ {
+ (*_passive_function)(
+ POET_REPEATED_ARG_NAMES(POET_ACTIVE_FUNCTION_NUM_ARGS, _arg));
+ _return_value.fulfill();
+ }
+ template <typename U>
+ void m_run(U *)
+ {
+ _return_value.fulfill((*_passive_function)(
+ POET_REPEATED_ARG_NAMES(POET_ACTIVE_FUNCTION_NUM_ARGS, _arg)));
+ }
+
+ promise<passive_result_type> _return_value;
+ // typename poet::future<boost::function_traits<Signature>::arg1_type> _arg1;
+ // typename poet::future<boost::function_traits<Signature>::arg2_type> _arg2;
+ // ...
+ // typename poet::future<boost::function_traits<Signature>::argN_type> _argN;
+ BOOST_PP_REPEAT(POET_ACTIVE_FUNCTION_NUM_ARGS, POET_ACTIVE_FUNCTION_ARG_DECLARATION, Signature)
+ boost::shared_ptr<boost::signals2::slot<Signature> > _passive_function;
+ };
+
+ template<typename Signature>
+ class POET_ACTIVE_FUNCTION_CLASS_NAME
+ {
+ public:
+ typedef typename boost::function_traits<Signature>::result_type passive_result_type;
+ typedef future<passive_result_type> result_type;
+ typedef boost::signals2::slot<Signature> passive_slot_type;
+
+ POET_ACTIVE_FUNCTION_CLASS_NAME()
+ {}
+ POET_ACTIVE_FUNCTION_CLASS_NAME(const passive_slot_type &passive_function,
+ boost::shared_ptr<scheduler_base> scheduler_in):
+ _passive_function(new passive_slot_type(passive_function)),
+ _scheduler(scheduler_in)
+ {
+ if(_scheduler == 0) _scheduler.reset(new scheduler);
+ }
+ virtual ~POET_ACTIVE_FUNCTION_CLASS_NAME() {}
+ result_type operator ()(POET_ACTIVE_FUNCTION_FULL_ARGS(POET_ACTIVE_FUNCTION_NUM_ARGS, Signature))
+ {
+ promise<passive_result_type> returnValue;
+ boost::shared_ptr<POET_AF_METHOD_REQUEST_CLASS_NAME<Signature> > methodRequest(
+ new POET_AF_METHOD_REQUEST_CLASS_NAME<Signature>(
+ returnValue, POET_REPEATED_ARG_NAMES(POET_ACTIVE_FUNCTION_NUM_ARGS, arg) BOOST_PP_COMMA_IF(POET_ACTIVE_FUNCTION_NUM_ARGS)
+ _passive_function));
+ _scheduler->post_method_request(methodRequest);
+ return returnValue;
+ }
+ result_type operator ()(POET_ACTIVE_FUNCTION_FULL_ARGS(POET_ACTIVE_FUNCTION_NUM_ARGS, Signature)) const
+ {
+ promise<passive_result_type> returnValue;
+ boost::shared_ptr<POET_AF_METHOD_REQUEST_CLASS_NAME<Signature> > methodRequest(
+ new POET_AF_METHOD_REQUEST_CLASS_NAME<Signature>(
+ returnValue, POET_REPEATED_ARG_NAMES(POET_ACTIVE_FUNCTION_NUM_ARGS, arg) BOOST_PP_COMMA_IF(POET_ACTIVE_FUNCTION_NUM_ARGS)
+ _passive_function));
+ _scheduler->post_method_request(methodRequest);
+ return returnValue;
+ }
+ bool expired() const {return _passive_function.expired();}
+ private:
+ boost::shared_ptr<passive_slot_type> _passive_function;
+ boost::shared_ptr<scheduler_base> _scheduler;
+ };
+
+ template<unsigned arity, typename Signature> class active_functionN;
+ // partial template specialization
+ template<typename Signature>
+ class active_functionN<POET_ACTIVE_FUNCTION_NUM_ARGS, Signature>
+ {
+ public:
+ typedef POET_ACTIVE_FUNCTION_CLASS_NAME<Signature> type;
+ };
+ }
+}
+
+#undef POET_ACTIVE_FUNCTION_NUM_ARGS
+#undef POET_ACTIVE_FUNCTION_CLASS_NAME
+#undef POET_ACTIVE_FUNCTION_ARG_TYPE
+#undef POET_ACTIVE_FUNCTION_FULL_ARG
+#undef POET_ACTIVE_FUNCTION_FULL_ARGS
+#undef POET_ACTIVE_FUNCTION_ARG_DECLARATION
+#undef POET_ACTIVE_FUNCTION_GET_TUPLE_ELEMENT
Added: sandbox/libpoet/trunk/poet/detail/active_object.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/active_object.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,222 @@
+/*
+ begin: Frank Hess <frank.hess_at_[hidden]> 2007-01-22
+*/
+
+// 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 <poet/active_object.hpp>
+#include <boost/bind.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <cassert>
+#include <poet/detail/nonvoid.hpp>
+#include <poet/future_barrier.hpp>
+#include <poet/future_select.hpp>
+
+namespace poet
+{
+ namespace detail
+ {
+ inline boost::shared_ptr<method_request_base> method_request_future_combiner(const boost::shared_ptr<method_request_base> &request, null_type)
+ {
+ return request;
+ };
+ inline exception_ptr method_request_future_exception_handler(const boost::shared_ptr<method_request_base> &request,
+ const exception_ptr &)
+ {
+ exception_ptr ep = poet::copy_exception(request);
+ return ep;
+ };
+
+ inline future<boost::shared_ptr<method_request_base> > make_method_request_future(
+ const boost::shared_ptr<method_request_base> &request)
+ {
+ BOOST_ASSERT(request);
+ return future_combining_barrier<boost::shared_ptr<method_request_base> >(
+ boost::bind(&method_request_future_combiner, request, _1),
+ boost::bind(&method_request_future_exception_handler, request, _1),
+ request->scheduling_guard());
+ }
+ }
+
+ void in_order_activation_queue::push_back(const boost::shared_ptr<method_request_base> &request)
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ if(_pendingRequests.empty())
+ _next_method_request.fulfill(detail::make_method_request_future(request));
+ _pendingRequests.push_back(request);
+ }
+
+ boost::shared_ptr<method_request_base> in_order_activation_queue::get_request()
+ {
+ future<boost::shared_ptr<method_request_base> > next;
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ next = future_select<boost::shared_ptr<method_request_base> >(_next_method_request, _wake_promise);
+ }
+ boost::shared_ptr<method_request_base> result;
+ try
+ {
+ result = next.get();
+ }
+ catch(const boost::shared_ptr<method_request_base> &method_request)
+ {
+ result = method_request;
+ }
+ catch(const std::exception &err)
+ {
+ std::cerr << "caught unexpected exception: " << err.what() << std::endl;
+ BOOST_ASSERT(false);
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ if(result)
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ _pendingRequests.pop_front();
+ _next_method_request.reset();
+ if(_pendingRequests.empty() == false)
+ _next_method_request.fulfill(detail::make_method_request_future(_pendingRequests.front()));
+ }
+ return result;
+ }
+
+ void in_order_activation_queue::wake()
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ _wake_promise.fulfill(boost::shared_ptr<method_request_base>());
+ _wake_promise.reset();
+ }
+
+ void out_of_order_activation_queue::push_back(const boost::shared_ptr<method_request_base> &request)
+ {
+ _selector.push(detail::make_method_request_future(request));
+ }
+
+ boost::shared_ptr<method_request_base> out_of_order_activation_queue::get_request()
+ {
+ future<boost::shared_ptr<method_request_base> > next;
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ next = future_select<boost::shared_ptr<method_request_base> >(_selector.selected(), _wake_promise);
+ }
+ boost::shared_ptr<method_request_base> result;
+ try
+ {
+ result = next.get();
+ }
+ catch(const boost::shared_ptr<method_request_base> &method_request)
+ {
+ result = method_request;
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ if(result)
+ {
+ _selector.pop_selected();
+ }
+ return result;
+ }
+
+ void out_of_order_activation_queue::wake()
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ _wake_promise.fulfill(boost::shared_ptr<method_request_base>());
+ _wake_promise.reset();
+ }
+
+ namespace detail
+ {
+ // scheduler_impl
+
+ scheduler_impl::scheduler_impl(const boost::shared_ptr<activation_queue_base> &activationQueue):
+ _activationQueue(activationQueue), _mortallyWounded(false),
+ _detached(false)
+ {
+ }
+
+ void scheduler_impl::post_method_request(const boost::shared_ptr<method_request_base> &methodRequest)
+ {
+ _activationQueue->push_back(methodRequest);
+ }
+
+ bool scheduler_impl::dispatch()
+ {
+ boost::shared_ptr<method_request_base> methodRequest = _activationQueue->get_request();
+ if(methodRequest) methodRequest->run();
+ return methodRequest;
+ }
+
+ void scheduler_impl::dispatcherThreadFunction(const boost::shared_ptr<scheduler_impl> &shared_this_in)
+ {
+ /* shared_this insures scheduler_impl object is not destroyed while its scheduler thread is still
+ running. */
+ boost::shared_ptr<scheduler_impl> shared_this = shared_this_in;
+ while(shared_this->mortallyWounded() == false)
+ {
+ boost::shared_ptr<method_request_base> next_request = shared_this->_activationQueue->get_request();
+ if(shared_this->mortallyWounded()) break;
+ try
+ {
+ if(next_request) next_request->run();
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ if(shared_this->detached() && shared_this->_activationQueue->empty())
+ {
+ break;
+ }
+ }
+ }
+
+ void scheduler_impl::kill()
+ {
+ {
+ boost::mutex::scoped_lock lock(_mutex);
+ _mortallyWounded = true;
+ }
+ _activationQueue->wake();
+ }
+
+ bool scheduler_impl::mortallyWounded() const
+ {
+ boost::mutex::scoped_lock lock(_mutex);
+ return _mortallyWounded;
+ }
+
+ void scheduler_impl::detach()
+ {
+ {
+ boost::mutex::scoped_lock lock(_mutex);
+ _detached = true;
+ }
+ _activationQueue->wake();
+ }
+ } // namespace detail
+
+ // scheduler
+
+ scheduler::scheduler(const boost::shared_ptr<activation_queue_base> &activationQueue):
+ _pimpl(new detail::scheduler_impl(activationQueue))
+ {
+ _dispatcherThread.reset(new boost::thread(boost::bind(&detail::scheduler_impl::dispatcherThreadFunction, _pimpl)));
+ }
+
+ void scheduler::join()
+ {
+ BOOST_ASSERT(_pimpl->mortallyWounded());
+ boost::thread thisThread;
+ if(thisThread == *_dispatcherThread)
+ {
+ throw std::invalid_argument("Cannot join scheduler thread from scheduler thread.");
+ }
+ _dispatcherThread->join();
+ }
+} // namespace poet
Added: sandbox/libpoet/trunk/poet/detail/condition.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/condition.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,45 @@
+/*
+ An slightly easier to use wrapper around boost::condition.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2007-01-30
+*/
+
+// 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 _POET_CONDITION_HPP
+#define _POET_CONDITION_HPP
+
+#include <boost/thread/condition.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/locks.hpp>
+
+namespace poet
+{
+ namespace detail
+ {
+ class condition: public boost::condition
+ {
+ public:
+ void locking_notify_all()
+ {
+ boost::mutex::scoped_lock lock(mutex);
+ notify_all();
+ }
+ template <typename Pred> void locking_wait(Pred predicate)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ wait(lock, predicate);
+ }
+ template <typename Timeout, typename Pred> void locking_timed_wait(const Timeout &t, Pred predicate)
+ {
+ boost::unique_lock<boost::mutex> lock(mutex);
+ timed_wait(lock, t, predicate);
+ }
+ mutable boost::mutex mutex;
+ };
+ }
+}
+
+#endif // _POET_CONDITION_HPP
Added: sandbox/libpoet/trunk/poet/detail/event_queue.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/event_queue.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,64 @@
+/*
+ Simple event queue inspired by asio::io_service, but without needing
+ thread-unsafe reset.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-31
+*/
+
+// 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 _POET_EVENT_QUEUE_HPP
+#define _POET_EVENT_QUEUE_HPP
+
+#include <boost/function.hpp>
+#include <boost/thread/mutex.hpp>
+#include <deque>
+namespace poet
+{
+ namespace detail
+ {
+ class event_queue
+ {
+ public:
+ typedef boost::function<void ()> event_type;
+ std::size_t poll_one()
+ {
+ std::size_t count = 0;
+ event_type event;
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ if(_queue.empty())
+ {
+ return count;
+ }else
+ {
+ event = _queue.front();
+ _queue.pop_front();
+ ++count;
+ }
+ }
+ event();
+ return count;
+ }
+ std::size_t poll()
+ {
+ std::size_t count = 0;
+ while(poll_one() == 1) ++count;
+ return count;
+ }
+ template<typename Event>
+ void post(const Event &event)
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ _queue.push_back(event);
+ }
+ private:
+ std::deque<event_type> _queue;
+ boost::mutex _mutex;
+ };
+ }
+}
+
+#endif // _POET_EVENT_QUEUE_HPP
Added: sandbox/libpoet/trunk/poet/detail/future_barrier_template.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/future_barrier_template.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,209 @@
+/*
+ Template for future_barrier and future_select overloads with
+ variable numbers of "const future<T> &" arguments.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-21
+*/
+
+// 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)
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#include <poet/detail/preprocessor_macros.hpp>
+
+#define POET_FUTURE_BARRIER_NUM_ARGS BOOST_PP_ITERATION()
+// const poet::future<Tn> &
+#define POET_FUTURE_BARRIER_ARG_TYPE(z, n, data) \
+ const poet::future<BOOST_PP_CAT(T, BOOST_PP_INC(n))> &
+// const poet::future<Tn> &namestemN
+#define POET_FUTURE_BARRIER_ARG_DECL(z, n, namestem) \
+ POET_FUTURE_BARRIER_ARG_TYPE(~, n, ~) POET_ARG_NAME(~, n, namestem)
+// const future<T1> &namestem1, const future<T2> &namestem2, ..., const future<Tn> &namestemN
+#define POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(arity, namestem) \
+ BOOST_PP_ENUM(arity, POET_FUTURE_BARRIER_ARG_DECL, namestem)
+// future_hetero_combining_barrier_body_N
+#define FUTURE_HETRO_COMBINING_BARRIER_BODY_N BOOST_PP_CAT(future_hetero_combining_barrier_body_, POET_FUTURE_BARRIER_NUM_ARGS)
+// combiner_invoker_N
+#define POET_COMBINER_INVOKER_N BOOST_PP_CAT(combiner_invoker_, POET_FUTURE_BARRIER_NUM_ARGS)
+
+namespace poet
+{
+ namespace detail
+ {
+ template<typename R, typename Combiner>
+ class POET_COMBINER_INVOKER_N
+ {
+ public:
+ POET_COMBINER_INVOKER_N(const Combiner &combiner):
+ _combiner(combiner)
+ {}
+ template<POET_REPEATED_TYPENAMES(POET_FUTURE_BARRIER_NUM_ARGS, T)>
+ void operator()(boost::optional<R> &result, POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(POET_FUTURE_BARRIER_NUM_ARGS, f))
+ {
+ result = _combiner(
+/*
+nonvoid_future_get<T1>(f1),
+nonvoid_future_get<T2>(f2),
+...
+nonvoid_future_get<TN>(fN)
+*/
+#define POET_MISC_STATEMENT(z, n, data) \
+ nonvoid_future_get<POET_ARG_NAME(~, n, T)>( POET_ARG_NAME(~, n, f) )
+ BOOST_PP_ENUM(POET_FUTURE_BARRIER_NUM_ARGS, POET_MISC_STATEMENT, ~)
+#undef POET_MISC_STATEMENT
+ );
+ }
+ private:
+ Combiner _combiner;
+ };
+ template<typename Combiner>
+ class POET_COMBINER_INVOKER_N<void, Combiner>
+ {
+ public:
+ POET_COMBINER_INVOKER_N(const Combiner &combiner):
+ _combiner(combiner)
+ {}
+ template<POET_REPEATED_TYPENAMES(POET_FUTURE_BARRIER_NUM_ARGS, T)>
+ void operator()(boost::optional<nonvoid<void>::type> &result,
+ POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(POET_FUTURE_BARRIER_NUM_ARGS, f))
+ {
+ _combiner(
+/*
+nonvoid_future_get<T1>(f1),
+nonvoid_future_get<T2>(f2),
+...
+nonvoid_future_get<TN>(fN)
+*/
+#define POET_MISC_STATEMENT(z, n, data) \
+ nonvoid_future_get<POET_ARG_NAME(~, n, T)>( POET_ARG_NAME(~, n, f) )
+ BOOST_PP_ENUM(POET_FUTURE_BARRIER_NUM_ARGS, POET_MISC_STATEMENT, ~)
+#undef POET_MISC_STATEMENT
+ );
+ result = null_type();
+ }
+ private:
+ Combiner _combiner;
+ };
+
+ template<typename R, typename Combiner, POET_REPEATED_TYPENAMES(POET_FUTURE_BARRIER_NUM_ARGS, T)>
+ class FUTURE_HETRO_COMBINING_BARRIER_BODY_N :
+ public future_body_base<R>, public future_barrier_body_base
+ {
+ typedef future_barrier_body_base barrier_base_class;
+ public:
+ static boost::shared_ptr<FUTURE_HETRO_COMBINING_BARRIER_BODY_N> create(
+ const Combiner &combiner, const barrier_base_class::exception_handler_type &exception_handler,
+ POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(POET_FUTURE_BARRIER_NUM_ARGS, input_future))
+ {
+ boost::shared_ptr<FUTURE_HETRO_COMBINING_BARRIER_BODY_N> new_object(
+ new FUTURE_HETRO_COMBINING_BARRIER_BODY_N(combiner, exception_handler,
+ POET_REPEATED_ARG_NAMES(POET_FUTURE_BARRIER_NUM_ARGS, input_future)));
+
+ std::vector<future<void> > input_futures;
+/*
+input_futures.push_back(input_future1);
+input_futures.push_back(input_future2);
+...
+input_futures.push_back(input_futureN);
+*/
+#define POET_MISC_STATEMENT(z, n, data) \
+ input_futures.push_back(POET_ARG_NAME(~, n, input_future));
+ BOOST_PP_REPEAT(POET_FUTURE_BARRIER_NUM_ARGS, POET_MISC_STATEMENT, ~)
+#undef POET_MISC_STATEMENT
+ barrier_base_class::init(new_object, input_futures.begin(), input_futures.end());
+ return new_object;
+ }
+ using barrier_base_class::ready;
+ using barrier_base_class::join;
+ using barrier_base_class::timed_join;
+ using barrier_base_class::cancel;
+ using barrier_base_class::get_exception_ptr;
+ virtual const typename nonvoid<R>::type& getValue() const
+ {
+ this->join();
+ if(this->_exception)
+ {
+ rethrow_exception(this->_exception);
+ }
+ return *this->_combiner_result;
+ }
+ virtual void setValue(const typename nonvoid<R>::type &value)
+ {
+ BOOST_ASSERT(false);
+ }
+ private:
+ FUTURE_HETRO_COMBINING_BARRIER_BODY_N(const Combiner &combiner,
+ const barrier_base_class::exception_handler_type &exception_handler,
+ POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(POET_FUTURE_BARRIER_NUM_ARGS, input_future)):
+#ifdef BOOST_MSVC
+#pragma warning( suppress : 4355 ) // suppress msvc 9 warning
+#endif
+ barrier_base_class(boost::bind(&FUTURE_HETRO_COMBINING_BARRIER_BODY_N::invoke_combiner, this), exception_handler),
+ POET_REPEATED_ARG_CONSTRUCTOR(POET_FUTURE_BARRIER_NUM_ARGS, input_future),
+ _combiner_invoker(combiner)
+ {
+ }
+
+ void invoke_combiner()
+ {
+ _combiner_invoker(_combiner_result,
+ POET_REPEATED_ARG_NAMES(POET_FUTURE_BARRIER_NUM_ARGS, _input_future));
+ }
+/*
+future<T1> _input_future1;
+future<T2> _input_future2;
+...
+future<TN> _input_futureN;
+*/
+#define POET_MISC_STATEMENT(z, n, data) \
+ future<POET_ARG_NAME(~, n, T)> POET_ARG_NAME(~, n, _input_future);
+ BOOST_PP_REPEAT(POET_FUTURE_BARRIER_NUM_ARGS, POET_MISC_STATEMENT, ~)
+#undef POET_MISC_STATEMENT
+ POET_COMBINER_INVOKER_N<R, Combiner> _combiner_invoker;
+ boost::optional<typename nonvoid<R>::type> _combiner_result;
+#ifdef BOOST_MSVC
+#pragma warning( suppress : 4250 ) // suppress msvc 9 warning
+#endif
+ };
+ }
+
+#if POET_FUTURE_BARRIER_NUM_ARGS > 1
+
+ template<POET_REPEATED_TYPENAMES(POET_FUTURE_BARRIER_NUM_ARGS, T)>
+ future<void> future_barrier(POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(POET_FUTURE_BARRIER_NUM_ARGS, f))
+ {
+ std::vector<future<void> > inputs;
+/*
+inputs.push_back(f1);
+inputs.push_back(f2);
+...
+inputs.push_back(fn);
+*/
+#define POET_MISC_STATEMENT(z, n, data) \
+ inputs.push_back(POET_ARG_NAME(~, n, f));
+ BOOST_PP_REPEAT(POET_FUTURE_BARRIER_NUM_ARGS, POET_MISC_STATEMENT, ~)
+#undef POET_MISC_STATEMENT
+ return future_barrier_range(inputs.begin(), inputs.end());
+ }
+
+#endif // POET_FUTURE_BARRIER_NUM_ARGS > 1
+
+ template<typename R, typename Combiner, typename ExceptionHandler, POET_REPEATED_TYPENAMES(POET_FUTURE_BARRIER_NUM_ARGS, T)>
+ future<R> future_combining_barrier(const Combiner &combiner, const ExceptionHandler &exception_handler,
+ POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS(POET_FUTURE_BARRIER_NUM_ARGS, f))
+ {
+ typedef detail::FUTURE_HETRO_COMBINING_BARRIER_BODY_N<R, Combiner, POET_REPEATED_ARG_NAMES(POET_FUTURE_BARRIER_NUM_ARGS, T)> body_type;
+ future<R> result = detail::create_future<R>(body_type::create(
+ combiner, exception_handler, POET_REPEATED_ARG_NAMES(POET_FUTURE_BARRIER_NUM_ARGS, f)));
+ return result;
+ }
+}
+
+#undef POET_FUTURE_BARRIER_NUM_ARGS
+#undef POET_FUTURE_BARRIER_ARG_TYPE
+#undef POET_FUTURE_BARRIER_ARG_DECL
+#undef POET_FUTURE_BARRIER_REPEATED_ARG_DECLARATIONS
+#undef FUTURE_HETRO_COMBINING_BARRIER_BODY_N
+#undef POET_COMBINER_INVOKER_N
Added: sandbox/libpoet/trunk/poet/detail/future_select_template.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/future_select_template.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,41 @@
+/*
+ Template for future_barrier and future_select overloads with
+ variable numbers of "const future<T> &" arguments.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-21
+*/
+
+// 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)
+
+// This file is included iteratively, and should not be protected from multiple inclusion
+
+#include <poet/detail/preprocessor_macros.hpp>
+
+#define POET_FUTURE_SELECT_NUM_ARGS BOOST_PP_ITERATION()
+// const poet::future<T> &fn
+#define POET_FUTURE_SELECT_ARG_DECL(z, n, data) \
+ const poet::future<T> & POET_ARG_NAME(~, n, f)
+// const future<T> &f1, const future<T> &f2, ..., const future<T> &fn
+#define POET_FUTURE_SELECT_REPEATED_ARG_DECLARATIONS(arity) \
+ BOOST_PP_ENUM(arity, POET_FUTURE_SELECT_ARG_DECL, ~)
+
+namespace poet
+{
+ template<typename T>
+ future<T> future_select(POET_FUTURE_SELECT_REPEATED_ARG_DECLARATIONS(POET_FUTURE_SELECT_NUM_ARGS))
+ {
+ std::vector<future<T> > inputs;
+// inputs.push_back(fn);
+#define POET_MISC_STATEMENT(z, n, data) \
+ inputs.push_back(POET_ARG_NAME(~, n, f));
+ BOOST_PP_REPEAT(POET_FUTURE_SELECT_NUM_ARGS, POET_MISC_STATEMENT, ~)
+#undef POET_MISC_STATEMENT
+ return future_select_range(inputs.begin(), inputs.end());
+ }
+}
+
+#undef POET_FUTURE_SELECT_NUM_ARGS
+#undef POET_FUTURE_SELECT_ARG_DECL
+#undef POET_FUTURE_SELECT_REPEATED_ARG_DECLARATIONS
Added: sandbox/libpoet/trunk/poet/detail/identity.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/identity.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,32 @@
+/*
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-06-08
+*/
+
+// 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 _POET_IDENTITY_HPP
+#define _POET_IDENTITY_HPP
+
+namespace poet
+{
+ namespace detail
+ {
+ struct identity
+ {
+ template<typename T>
+ const T& operator()(const T &t) const
+ {
+ return t;
+ }
+ template<typename T>
+ T& operator()(T &t) const
+ {
+ return t;
+ }
+ };
+ }
+}
+
+#endif //_POET_IDENTITY_HPP
Added: sandbox/libpoet/trunk/poet/detail/monitor_base.ipp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/monitor_base.ipp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,34 @@
+/*
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-08-27
+*/
+
+// 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 _POET_MONITOR_BASE_IPP
+#define _POET_MONITOR_BASE_IPP
+
+#include <poet/monitor_base.hpp>
+
+namespace poet
+{
+ void monitor_base::wait() const
+ {
+ _syncer->wait();
+ }
+ void monitor_base::notify_one() const
+ {
+ _syncer->notify_one();
+ }
+ void monitor_base::notify_all() const
+ {
+ _syncer->notify_all();
+ }
+ void monitor_base::set_synchronizer(const boost::shared_ptr<detail::monitor_synchronizer_base> &syncer) const
+ {
+ _syncer = syncer;
+ }
+};
+
+#endif // _POET_MONITOR_BASE_IPP
Added: sandbox/libpoet/trunk/poet/detail/monitor_synchronizer.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/monitor_synchronizer.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,77 @@
+/*
+ A wrapper which automatically locks/unlocks a mutex whenever the wrapped
+ objects members are accessed. See "Wrapping C++ Member Function Calls"
+ by Bjarne Stroustroup at http://www.research.att.com/~bs/wrapper.pdf
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-08-27
+*/
+
+// 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 _POET_MONITOR_SYNCHRONIZER_HPP
+#define _POET_MONITOR_SYNCHRONIZER_HPP
+
+#include <boost/function.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/condition.hpp>
+
+namespace boost
+{
+ class mutex;
+};
+
+namespace poet
+{
+ namespace detail
+ {
+ class monitor_synchronizer_base
+ {
+ public:
+ typedef boost::function<void (boost::condition &, const boost::function<bool ()> &)> wait_function_type;
+
+ virtual ~monitor_synchronizer_base()
+ {}
+
+ void wait()
+ {
+ wait_function_type wait_func = _wait_func;
+ _wait_func(_condition, boost::function<bool ()>());
+ // restore _wait_func after we have lock again
+ _wait_func = wait_func;
+ }
+ void wait(const boost::function<bool ()> &pred)
+ {
+ wait_function_type wait_func = _wait_func;
+ _wait_func(_condition, pred);
+ // restore _wait_func after we have lock again
+ _wait_func = wait_func;
+ }
+ void notify_one()
+ {
+ _condition.notify_one();
+ }
+ void notify_all()
+ {
+ _condition.notify_all();
+ }
+ void set_wait_function(const wait_function_type &wait_func)
+ {
+ _wait_func = wait_func;
+ }
+ protected:
+ boost::condition _condition;
+ wait_function_type _wait_func;
+ };
+
+ template<typename Mutex>
+ class monitor_synchronizer: public monitor_synchronizer_base
+ {
+ public:
+ Mutex _mutex;
+ };
+ };
+};
+
+#endif // _POET_MONITOR_SYNCHRONIZER_HPP
Added: sandbox/libpoet/trunk/poet/detail/mutex_grapher.ipp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/mutex_grapher.ipp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,180 @@
+/*
+ A thread-safe singleton class which can be used build up a graph of a
+ program's locking order for mutexes, and check it for locking
+ order violations.
+
+ begin: Frank Mori Hess <fmhess_at_[hidden]> 2007-10-26
+ copyright (c) Frank Mori Hess 2007-2008
+*/
+
+// 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 _POET_MUTEX_GRAPHER_IPP
+#define _POET_MUTEX_GRAPHER_IPP
+
+#include <poet/mutex_grapher.hpp>
+
+#include <boost/graph/topological_sort.hpp>
+#include <boost/graph/graphviz.hpp>
+#include <cassert>
+#include <cstdlib>
+#include <list>
+#include <map>
+#include <poet/acyclic_mutex_base.hpp>
+#include <poet/mutex_properties.hpp>
+#include <sstream>
+#include <string>
+#include <vector>
+
+namespace poet
+{
+ mutex_grapher::mutex_grapher(): _cycle_detected(false),
+ _cycle_handler(&default_cycle_handler)
+ {}
+
+ template<typename AcyclicMutex>
+ bool mutex_grapher::track_lock(AcyclicMutex &mutex)
+ {
+ // we want to ignore all locking events after the first cycle is detected.
+ if(_cycle_detected) return false;
+
+ if(mutex.vertex() == 0)
+ {
+ acquire_vertex(mutex);
+ }
+ if(locked_mutexes().empty() == false)
+ {
+ const typename locking_order_graph::vertex_descriptor source_vertex = *locked_mutexes().back()->vertex();
+ typename locking_order_graph::edge_descriptor new_edge = boost::add_edge(source_vertex,
+ *mutex.vertex(), _graph).first;
+ try
+ {
+ check_for_cycles();
+ }
+ catch(const boost::not_a_dag &)
+ {
+ _cycle_detected = true;
+ _graph[new_edge].locking_order_violation = true;
+ }
+ }
+ internal_locked_mutexes().push_back(&mutex);
+ return _cycle_detected;
+ };
+
+ void mutex_grapher::track_unlock(const acyclic_mutex_base &mutex)
+ {
+ // we want to ignore all locking events after the first cycle is detected.
+ if(_cycle_detected) return;
+
+ mutex_list_type::reverse_iterator rit = std::find(internal_locked_mutexes().rbegin(), internal_locked_mutexes().rend(), &mutex);
+ assert(rit != internal_locked_mutexes().rend());
+ internal_locked_mutexes().erase(--(rit.base()));
+ }
+
+ void mutex_grapher::write_graphviz(std::ostream &out_stream) const
+ {
+ boost::write_graphviz(out_stream, graph(), vertex_labeler(graph()), edge_colorer(graph()));
+ }
+
+ void mutex_grapher::check_for_cycles() const
+ {
+ typedef std::vector<locking_order_graph::vertex_descriptor> result_type;
+ result_type result;
+ // throws boost::not_a_dag if graph has cycles
+ boost::topological_sort(_graph, std::back_inserter(result));
+ }
+
+ void mutex_grapher::default_cycle_handler()
+ {
+ std::cerr << "mutex_grapher::default_cycle_handler(): cycle detected in mutex locking order." << std::endl;
+ std::abort();
+ }
+
+ template<typename AcyclicMutex>
+ void mutex_grapher::acquire_vertex(AcyclicMutex &mutex)
+ {
+ typedef detail::vertex_finder<typename AcyclicMutex::key_type, typename AcyclicMutex::key_compare> vertex_finder_type;
+ const typename locking_order_graph::vertex_descriptor *found_vertex = 0;
+ typename locking_order_graph::vertex_descriptor new_vertex;
+ typename vertex_finder_type::scoped_lock finder;
+ if(mutex.node_key())
+ {
+ found_vertex = finder->find_vertex(*mutex.node_key());
+ }
+ if(found_vertex)
+ {
+ new_vertex = *found_vertex;
+ }else
+ {
+ if(_free_vertices.size() > 0)
+ {
+ new_vertex = _free_vertices.back();
+ _free_vertices.pop_back();
+ }else
+ {
+ new_vertex = boost::add_vertex(_graph);
+ }
+ std::ostringstream node_name;
+ if(mutex.node_key())
+ node_name << *mutex.node_key();
+ else
+ node_name << "mutex " << new_vertex;
+ _graph[new_vertex].name = node_name.str();
+ if(mutex.node_key())
+ finder->add_vertex(*mutex.node_key(), new_vertex);
+ }
+ mutex.set_vertex(new_vertex);
+ ++_graph[new_vertex].use_count;
+ }
+
+ template<typename AcyclicMutex>
+ void mutex_grapher::release_vertex(const AcyclicMutex &mutex)
+ {
+ // we want to ignore all locking events after the first cycle is detected.
+ if(_cycle_detected) return;
+
+ if(!mutex.vertex()) return;
+ const typename locking_order_graph::vertex_descriptor vertex = *mutex.vertex();
+
+ --_graph[vertex].use_count;
+ assert(_graph[vertex].use_count >= 0);
+ if(_graph[vertex].use_count > 0) return;
+
+ /* Connect all source vertices of incoming edges and to the target vertex of each outgoing edge,
+ then delete all edges connected to the removed vertex. */
+ std::pair<locking_order_graph::in_edge_iterator, locking_order_graph::in_edge_iterator> in_edges =
+ boost::in_edges(vertex, _graph);
+ locking_order_graph::in_edge_iterator in_it;
+ for(in_it = in_edges.first; in_it != in_edges.second; ++in_it)
+ {
+ std::pair<locking_order_graph::out_edge_iterator, locking_order_graph::out_edge_iterator> out_edges =
+ boost::out_edges(vertex, _graph);
+ locking_order_graph::out_edge_iterator out_it;
+ for(out_it = out_edges.first; out_it != out_edges.second; ++out_it)
+ {
+ const locking_order_graph::vertex_descriptor source = boost::source(*in_it, _graph);
+ const locking_order_graph::vertex_descriptor target = boost::target(*out_it, _graph);
+ assert(source != vertex);
+ assert(target != vertex);
+ boost::add_edge(source, target, _graph);
+ }
+ }
+ boost::clear_vertex(vertex, _graph);
+
+ // clear key key from finder
+ if(mutex.node_key())
+ {
+ typedef detail::vertex_finder<typename AcyclicMutex::key_type, typename AcyclicMutex::key_compare> vertex_finder_type;
+ typename vertex_finder_type::scoped_lock finder;
+ finder->remove_vertex(*mutex.node_key());
+ }
+
+ /* We don't actually remove the vertex from the graph, since that would invalidate all the
+ other vertex descriptors. Instead, we maintain a list of vertices available for reuse. */
+ _free_vertices.push_back(vertex);
+ }
+};
+
+#endif // _POET_MUTEX_GRAPHER_IPP
Added: sandbox/libpoet/trunk/poet/detail/mutex_grapher_decl.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/mutex_grapher_decl.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,234 @@
+/*
+ A thread-safe singleton class which can be used build up a graph of a
+ program's locking order for mutexes, and check it for locking
+ order violations.
+
+ begin: Frank Mori Hess <fmhess_at_[hidden]> 2007-10-26
+ copyright (c) Frank Mori Hess 2007-2008
+*/
+
+// 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 _POET_MUTEX_GRAPHER_DECL_HPP
+#define _POET_MUTEX_GRAPHER_DECL_HPP
+
+#include <boost/function.hpp>
+#include <boost/graph/adjacency_list.hpp>
+#include <boost/optional.hpp>
+#include <boost/thread/once.hpp>
+#include <boost/thread/tss.hpp>
+#include <boost/noncopyable.hpp>
+#include <cassert>
+#include <list>
+#include <map>
+#include <poet/detail/template_static.hpp>
+#include <poet/monitor_ptr.hpp>
+#include <poet/monitor_locks.hpp>
+#include <string>
+
+namespace poet
+{
+ // forward declarations
+ class acyclic_mutex_base;
+ template<typename Mutex, typename Key, typename KeyCompare>
+ class acyclic_mutex;
+ namespace detail
+ {
+ template<typename AcyclicMutex>
+ class acyclic_scoped_lock;
+
+ template<typename AssociatedClass> class template_static_once_flag
+ {
+ public:
+ static boost::once_flag flag;
+ };
+ template<typename AssociatedClass>
+ boost::once_flag template_static_once_flag<AssociatedClass>::flag = BOOST_ONCE_INIT;
+ };
+
+ class mutex_grapher: public boost::noncopyable
+ {
+ typedef monitor_ptr<mutex_grapher, boost::mutex> monitor_type;
+ public:
+ struct vertex_properties
+ {
+ vertex_properties(): use_count(0) {}
+ std::string name;
+ int use_count;
+ };
+ struct edge_properties
+ {
+ edge_properties(): locking_order_violation(false) {}
+ bool locking_order_violation;
+ };
+ typedef boost::adjacency_list<boost::setS, boost::vecS, boost::bidirectionalS, vertex_properties, edge_properties>
+ locking_order_graph;
+ typedef std::list<const acyclic_mutex_base *> mutex_list_type;
+ class unique_lock: public monitor_unique_lock<monitor_type>
+ {
+ public:
+ unique_lock(): monitor_unique_lock<monitor_type>(mutex_grapher::instance())
+ {}
+ };
+ typedef unique_lock scoped_lock;
+
+ const locking_order_graph& graph() const {return _graph;}
+ inline void write_graphviz(std::ostream &out_stream) const;
+ template<typename Func>
+ void set_cycle_handler(Func func)
+ {
+ _cycle_handler = func;
+ }
+ const mutex_list_type& locked_mutexes() const
+ {
+ check_locked_mutexes_init();
+ return *_locked_mutexes;
+ }
+ private:
+ class vertex_labeler
+ {
+ public:
+ vertex_labeler(const locking_order_graph &graph): _graph(graph)
+ {}
+ void operator()(std::ostream &output_stream, locking_order_graph::vertex_descriptor vertex)
+ {
+ output_stream << "[label=\"" << _graph[vertex].name << "\"]";
+ }
+ private:
+ const locking_order_graph &_graph;
+ };
+ class edge_colorer
+ {
+ public:
+ edge_colorer(const locking_order_graph &graph): _graph(graph)
+ {}
+ void operator()(std::ostream &output_stream, locking_order_graph::edge_descriptor edge)
+ {
+ output_stream << "[color=\"";
+ if(_graph[edge].locking_order_violation)
+ {
+ output_stream << "red";
+ }else
+ {
+ output_stream << "black";
+ }
+ output_stream << "\"]";
+ }
+ private:
+ const locking_order_graph &_graph;
+ };
+ template<typename Mutex, bool recursive, enum mutex_model model, typename Key, typename KeyCompare>
+ friend class detail::specialized_acyclic_mutex;
+ template<typename Mutex, typename Key, typename KeyCompare>
+ friend class acyclic_mutex;
+
+ inline mutex_grapher();
+
+ void check_locked_mutexes_init() const
+ {
+ if(_locked_mutexes.get() == 0)
+ {
+ _locked_mutexes.reset(new mutex_list_type);
+ }
+ }
+ mutex_list_type& internal_locked_mutexes()
+ {
+ check_locked_mutexes_init();
+ return *_locked_mutexes;
+ }
+ template<typename AcyclicMutex>
+ inline bool track_lock(AcyclicMutex &_mutex);
+ inline void track_unlock(const acyclic_mutex_base &_mutex);
+ inline void check_for_cycles() const;
+ template<typename AcyclicMutex>
+ inline void acquire_vertex(AcyclicMutex &mutex);
+ template<typename AcyclicMutex>
+ inline void release_vertex(const AcyclicMutex &mutex);
+
+ // static functions
+ static monitor_type& instance()
+ {
+ static monitor_type *grapher;
+ boost::call_once(detail::template_static_once_flag<mutex_grapher>::flag,
+ boost::bind(&mutex_grapher::init_grapher_instance, &grapher));
+ return *grapher;
+ }
+ static void init_grapher_instance(monitor_type **grapher)
+ {
+ *grapher = new monitor_type(new mutex_grapher);
+ }
+ inline static void default_cycle_handler();
+
+ locking_order_graph _graph;
+ bool _cycle_detected;
+ mutable boost::thread_specific_ptr<mutex_list_type> _locked_mutexes;
+ boost::function<void ()> _cycle_handler;
+ std::vector<locking_order_graph::vertex_descriptor> _free_vertices;
+ };
+
+ namespace detail
+ {
+ template<typename Key, typename KeyCompare>
+ class vertex_finder
+ {
+ typedef monitor_ptr<vertex_finder, boost::mutex> monitor_type;
+ public:
+ typedef Key key_type;
+ typedef KeyCompare key_compare;
+ typedef mutex_grapher::locking_order_graph::vertex_descriptor vertex_descriptor_type;
+ typedef std::map<Key, vertex_descriptor_type, KeyCompare> vertex_map_type;
+ class scoped_lock: public monitor_type::scoped_lock
+ {
+ public:
+ scoped_lock(): monitor_type::scoped_lock(vertex_finder::instance())
+ {}
+ };
+
+ const vertex_descriptor_type* find_vertex(const Key &key) const
+ {
+ typename vertex_map_type::const_iterator it = _vertex_map.find(key);
+ if(it == _vertex_map.end())
+ {
+ return 0;
+ }else
+ {
+ return &it->second;
+ }
+ }
+ void add_vertex(const Key &key, vertex_descriptor_type vertex)
+ {
+ _vertex_map[key] = vertex;
+ }
+ void remove_vertex(const Key &key)
+ {
+ _vertex_map.erase(key);
+ }
+ private:
+ vertex_finder() {}
+
+ // static functions
+ static monitor_type& instance()
+ {
+ static monitor_type *finder;
+
+ boost::call_once(_instance_init_flag,
+ boost::bind(&vertex_finder::init_finder_instance, &finder));
+
+ return *finder;
+ }
+ static void init_finder_instance(monitor_type **finder)
+ {
+ *finder = new monitor_type(new vertex_finder);
+ }
+
+ vertex_map_type _vertex_map;
+ static boost::once_flag _instance_init_flag;
+ };
+ template<typename Key, typename KeyCompare>
+ boost::once_flag vertex_finder<Key, KeyCompare>::_instance_init_flag;
+ };
+};
+
+#endif // _POET_MUTEX_GRAPHER_DECL_HPP
Added: sandbox/libpoet/trunk/poet/detail/nonvoid.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/nonvoid.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,33 @@
+/*
+ Maps void type to bogus int, leaves all other types the same.
+ Added to ease generic programming while dealing with future<void> issues.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-28
+*/
+
+// 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 _POET_NONVOID_HPP
+#define _POET_NONVOID_HPP
+
+#include <boost/mpl/if.hpp>
+#include <boost/type_traits.hpp>
+#include <poet/null_type.hpp>
+
+namespace poet
+{
+ namespace detail
+ {
+
+ template<typename T>
+ class nonvoid
+ {
+ public:
+ typedef typename boost::mpl::if_<boost::is_void<T>, null_type, T>::type type;
+ };
+ }
+}
+
+#endif //_POET_NONVOID_HPP
Added: sandbox/libpoet/trunk/poet/detail/preprocessor_macros.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/preprocessor_macros.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,37 @@
+/*
+ Some macros for feeding into the boost preprocessor for
+ repetitive code generation.
+
+ Author: Frank Hess <frank.hess_at_[hidden]>
+ Begin: 2007-01-26
+*/
+
+// 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 _POET_PREPROCESSOR_MACROS_HPP
+#define _POET_PREPROCESSOR_MACROS_HPP
+
+// nameStem(n + 1)
+#define POET_ARG_NAME(z, n, nameStem) BOOST_PP_CAT(nameStem, BOOST_PP_INC(n))
+// nameStem1, nameStem2, ... , nameStemn
+#define POET_REPEATED_ARG_NAMES(arity, nameStem) \
+ BOOST_PP_ENUM(arity, POET_ARG_NAME, nameStem)
+// typename prefix1, typename prefix2, ..., typename prefixN
+#define POET_REPEATED_TYPENAMES(arity, prefix) \
+ BOOST_PP_ENUM_SHIFTED_PARAMS(BOOST_PP_INC(arity), typename prefix)
+// type_prefixN argN
+#define POET_ARG_DECLARATION(z, n, type_prefix) \
+ BOOST_PP_CAT(type_prefix, BOOST_PP_INC(n)) BOOST_PP_CAT(arg, BOOST_PP_INC(n))
+// type_prefix1 arg1, type_prefix2 arg2, ..., type_prefixn argn
+#define POET_REPEATED_ARG_DECLARATIONS(arity, type_prefix) \
+ BOOST_PP_ENUM(arity, POET_ARG_DECLARATION, type_prefix)
+// _nameN ( nameN )
+#define POET_ARG_CONSTRUCTOR(z, n, name) \
+ POET_ARG_NAME(~, n, BOOST_PP_CAT(_, name)) ( POET_ARG_NAME(~, n, name) )
+// _name1 ( name1 ), _name2 ( name2), ..., _nameN ( nameN )
+#define POET_REPEATED_ARG_CONSTRUCTOR(arity, name) \
+ BOOST_PP_ENUM(arity, POET_ARG_CONSTRUCTOR, name)
+
+#endif // _POET_PREPROCESSOR_MACROS_HPP
Added: sandbox/libpoet/trunk/poet/detail/template_static.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/template_static.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,29 @@
+/*
+ A hack to add static members to non-template classes without
+ needing a compiled lib to hold definition.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-10-26
+*/
+
+// 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 _POET_TEMPLATE_STATIC_HPP
+#define _POET_TEMPLATE_STATIC_HPP
+
+namespace poet
+{
+ namespace detail
+ {
+ template<typename AssociatedClass, typename T> class template_static
+ {
+ public:
+ static T object;
+ };
+ template<typename AssociatedClass, typename T>
+ T template_static<AssociatedClass, T>::object;
+ };
+};
+
+#endif // _POET_STATIC_MUTEX_HPP
Added: sandbox/libpoet/trunk/poet/detail/utility.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/detail/utility.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,39 @@
+// copyright (c) Frank Mori Hess <fmhess_at_[hidden]> 2008-04-13
+
+// 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 _POET_DETAIL_UTILITY_HPP
+#define _POET_DETAIL_UTILITY_HPP
+
+#include <boost/weak_ptr.hpp>
+
+namespace poet
+{
+ namespace detail
+ {
+ // deadlock-free locking of a pair of locks with arbitrary locking order
+ template<typename LockT, typename LockU>
+ void lock_pair(LockT &a, LockU &b)
+ {
+ while(true)
+ {
+ a.lock();
+ if(b.try_lock()) return;
+ a.unlock();
+ b.lock();
+ if(a.try_lock()) return;
+ b.unlock();
+ }
+ }
+
+ template<typename T>
+ boost::weak_ptr<T> make_weak(const boost::shared_ptr<T> &sp)
+ {
+ return boost::weak_ptr<T>(sp);
+ }
+ }
+}
+
+#endif // _POET_DETAIL_UTILITY_HPP
Added: sandbox/libpoet/trunk/poet/exception_ptr.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/exception_ptr.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,96 @@
+// Copyright (c) 2007 Frank Mori Hess
+// Copyright (c) 2007 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <poet/exception_ptr.hpp>
+#include <exception>
+#include <poet/detail/template_static.hpp>
+#include <stdexcept>
+// for libpoet exceptions
+#include <poet/exceptions.hpp>
+// for bad_weak_ptr
+#include <boost/weak_ptr.hpp>
+// for no_slots_error
+#include <boost/signals2/last_value.hpp>
+// for expired_slot
+#include <boost/signals2/slot.hpp>
+
+namespace poet
+{
+ namespace detail
+ {
+ static poet::exception_ptr _exp_current_exception();
+ class s_bad_alloc
+ {
+ public:
+ s_bad_alloc():
+ ep(new poet::detail::_exp_throwable_impl< std::bad_alloc >)
+ {}
+ poet::exception_ptr ep;
+ };
+ }
+}
+
+#define _CATCH_AND_RETURN( E ) catch( E const & e ) { return poet::exception_ptr( new poet::detail::_exp_throwable_impl< E >( e ) ); }
+#define _CATCH_AND_RETURN_WHAT( E ) catch( E const & e ) { return poet::exception_ptr( new poet::detail::_exp_throwable_impl< E >( e.what() ) ); }
+
+static poet::exception_ptr poet::detail::_exp_current_exception()
+{
+ try
+ {
+ throw;
+ }
+
+ _CATCH_AND_RETURN_WHAT( std::invalid_argument )
+ _CATCH_AND_RETURN_WHAT( std::out_of_range )
+ _CATCH_AND_RETURN_WHAT( std::domain_error )
+ _CATCH_AND_RETURN_WHAT( std::length_error )
+ _CATCH_AND_RETURN_WHAT( std::logic_error )
+
+ _CATCH_AND_RETURN_WHAT( poet::unknown_exception )
+ _CATCH_AND_RETURN( poet::cancelled_future )
+ _CATCH_AND_RETURN( poet::uncertain_future )
+ _CATCH_AND_RETURN_WHAT( std::overflow_error )
+ _CATCH_AND_RETURN_WHAT( std::underflow_error )
+ _CATCH_AND_RETURN_WHAT( std::range_error )
+ _CATCH_AND_RETURN_WHAT( std::runtime_error )
+
+ _CATCH_AND_RETURN( boost::signals2::expired_slot )
+ _CATCH_AND_RETURN( boost::bad_weak_ptr )
+
+ _CATCH_AND_RETURN( boost::signals2::no_slots_error )
+ _CATCH_AND_RETURN( std::bad_alloc )
+ _CATCH_AND_RETURN( std::bad_cast )
+ _CATCH_AND_RETURN( std::bad_typeid )
+ _CATCH_AND_RETURN( std::bad_exception )
+
+ // throw std::exception as poet::unknown_exception, since we can't initialize what() string using a std::exception
+ catch( std::exception const & e )
+ {
+ return poet::exception_ptr( new poet::detail::_exp_throwable_impl<poet::unknown_exception>( e.what() ) );
+ }
+ catch( ... )
+ {
+ return poet::exception_ptr( new poet::detail::_exp_throwable_impl<poet::unknown_exception>() );
+ }
+}
+
+poet::exception_ptr poet::current_exception()
+{
+ try
+ {
+ return detail::_exp_current_exception();
+ }
+ catch( std::bad_alloc const & )
+ {
+ return detail::template_static<exception_ptr, detail::s_bad_alloc>::object.ep;
+ }
+}
+
+void poet::rethrow_exception( exception_ptr p )
+{
+ BOOST_ASSERT(p);
+ p->rethrow();
+}
Added: sandbox/libpoet/trunk/poet/exception_ptr.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/exception_ptr.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,63 @@
+#ifndef POET_EXCEPTION_PTR_HPP_INCLUDED
+#define POET_EXCEPTION_PTR_HPP_INCLUDED
+
+// Copyright (c) 2007 Frank Mori Hess
+// Copyright (c) 2007 Peter Dimov
+//
+// Distributed under the Boost Software License, Version 1.0.
+// http://www.boost.org/LICENSE_1_0.txt
+
+#include <boost/shared_ptr.hpp>
+#include <poet/exceptions.hpp>
+
+namespace poet
+{
+ namespace detail
+ {
+ class _exp_throwable
+ {
+ protected:
+
+ virtual ~_exp_throwable() {}
+
+ public:
+
+ virtual void rethrow() = 0;
+ };
+
+ template< class E > class _exp_throwable_impl: public _exp_throwable
+ {
+ private:
+
+ E e_;
+
+ public:
+
+ _exp_throwable_impl()
+ {
+ }
+
+ template< class A > _exp_throwable_impl( A const & a ): e_( a )
+ {
+ }
+
+ void rethrow()
+ {
+ throw e_;
+ }
+ };
+ }
+ typedef boost::shared_ptr<detail::_exp_throwable > exception_ptr;
+ inline exception_ptr current_exception();
+ inline void rethrow_exception( exception_ptr p );
+ template< class E >
+ poet::exception_ptr copy_exception( E const & e )
+ {
+ exception_ptr exp(new detail::_exp_throwable_impl<E>(e));
+ return exp;
+ }
+}
+
+#include <poet/exception_ptr.cpp>
+
+#endif // #ifndef POET_EXCEPTION_PTR_HPP_INCLUDED
Added: sandbox/libpoet/trunk/poet/exceptions.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/exceptions.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,47 @@
+/*
+ poet::future defines a templated future class which can be used,
+ for example, to implement "active objects" and asynchronous function
+ calls. See the paper "Active Object, An Object Behavioral Pattern for
+ Concurrent Programming." by R. Greg Lavender and Douglas C. Schmidt
+ for more information about active objects and futures.
+
+ Active objects that use futures for both input parameters and
+ return values can be chained together in pipelines or do
+ dataflow-like processing, thereby achieving good concurrency.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2007-01-22
+*/
+// 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 _POET_EXCEPTIONS_H
+#define _POET_EXCEPTIONS_H
+
+namespace poet
+{
+ class cancelled_future: public std::runtime_error
+ {
+ public:
+ cancelled_future(): std::runtime_error("poet::cancelled_future")
+ {}
+ virtual ~cancelled_future() throw() {}
+ };
+ class uncertain_future: public std::runtime_error
+ {
+ public:
+ uncertain_future(): std::runtime_error("poet::uncertain_future")
+ {}
+ virtual ~uncertain_future() throw() {}
+ };
+ class unknown_exception: public std::runtime_error
+ {
+ public:
+ unknown_exception(const std::string &description = "poet::unknown_exception"):
+ runtime_error(description)
+ {}
+ virtual ~unknown_exception() throw() {}
+ };
+}
+
+#endif // _POET_EXCEPTIONS_H
Added: sandbox/libpoet/trunk/poet/future.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/future.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,981 @@
+/*
+ poet::future defines a templated future class which can be used,
+ for example, to implement "active objects" and asynchronous function
+ calls. See the paper "Active Object, An Object Behavioral Pattern for
+ Concurrent Programming." by R. Greg Lavender and Douglas C. Schmidt
+ for more information about active objects and futures.
+
+ Active objects that use futures for both input parameters and
+ return values can be chained together in pipelines or do
+ dataflow-like processing, thereby achieving good concurrency.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2007-01-22
+*/
+
+// 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 _POET_FUTURE_H
+#define _POET_FUTURE_H
+
+#include <boost/assert.hpp>
+#include <boost/bind.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/optional.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/thread_time.hpp>
+#include <boost/signals2/signal.hpp>
+#include <boost/weak_ptr.hpp>
+#include <poet/detail/condition.hpp>
+#include <poet/detail/event_queue.hpp>
+#include <poet/detail/nonvoid.hpp>
+#include <poet/detail/utility.hpp>
+#include <poet/exception_ptr.hpp>
+#include <poet/exceptions.hpp>
+#include <iostream>
+#include <iterator>
+#include <sstream>
+#include <stdexcept>
+#include <typeinfo>
+
+namespace poet
+{
+ template <typename T>
+ class future;
+
+ namespace detail
+ {
+ // forward declarations
+ class future_body_untyped_base;
+ template<typename T>
+ class future_body_base;
+ template<typename T>
+ class nonvoid_future_body_base
+ {
+ public:
+ typedef future_body_base<T> type;
+ };
+ template<>
+ class nonvoid_future_body_base<void>
+ {
+ public:
+ typedef future_body_untyped_base type;
+ };
+ template<typename T>
+ const boost::shared_ptr<typename nonvoid_future_body_base<T>::type>& get_future_body(const poet::future<T> &f);
+
+ /* class for holding wait callbacks. Any thread can post a functor to the waiter_event_queue,
+ but only future-waiting threads should pop them off and execute them. */
+ class waiter_event_queue
+ {
+ typedef boost::signals2::signal<void (const event_queue::event_type &)> event_posted_type;
+ typedef event_posted_type::slot_type slot_type;
+ typedef std::vector<boost::signals2::connection> connections_type;
+ public:
+ waiter_event_queue(boost::mutex &condition_mutex, boost::condition &condition):
+ _condition_mutex(condition_mutex), _condition(condition), _posting_closed(false)
+ {}
+
+ void set_owner(const boost::shared_ptr<const void> &queue_owner)
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ boost::shared_ptr<waiter_event_queue> shared_this(queue_owner, this);
+ _weak_this = shared_this;
+ }
+ template<typename Event>
+ void post(const Event &event)
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+
+ if(_posting_closed) return;
+ }
+ _events.post(event);
+ _event_posted(create_poll_event());
+ {
+ boost::unique_lock<boost::mutex> lock(_condition_mutex);
+ _condition.notify_all();
+ }
+ }
+ void poll()
+ {
+ _events.poll();
+ }
+ boost::signals2::connection observe(waiter_event_queue &other)
+ {
+ boost::signals2::connection connection;
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+
+ if(_posting_closed) return connection;
+
+ slot_type slot(&waiter_event_queue::post<event_queue::event_type>, this, _1);
+ BOOST_ASSERT(_weak_this.expired() == false);
+ slot.track(_weak_this);
+ connection = other._event_posted.connect(slot);
+ _connections.push_back(connection);
+ }
+ post(other.create_poll_event());
+ return connection;
+ }
+ void close_posting()
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+
+ _posting_closed = true;
+
+ connections_type::iterator it;
+ for(it = _connections.begin(); it != _connections.end(); ++it)
+ {
+ it->disconnect();
+ }
+ }
+ private:
+ event_queue::event_type create_poll_event() const
+ {
+ BOOST_ASSERT(_weak_this.expired() == false);
+ event_queue::event_type event = boost::bind(&waiter_event_queue::poll_event_impl, _weak_this);
+ return event;
+ }
+ static void poll_event_impl(const boost::weak_ptr<waiter_event_queue> &weak_this)
+ {
+ boost::shared_ptr<waiter_event_queue> shared_this = weak_this.lock();
+ if(!shared_this) return;
+ shared_this->poll();
+ }
+
+ event_queue _events;
+ boost::mutex _mutex;
+ boost::mutex &_condition_mutex;
+ boost::condition &_condition;
+ event_posted_type _event_posted;
+ boost::weak_ptr<waiter_event_queue> _weak_this;
+ connections_type _connections;
+ bool _posting_closed;
+ };
+
+ class future_body_untyped_base: public boost::enable_shared_from_this<future_body_untyped_base>
+ {
+ public:
+ typedef boost::signals2::signal<void ()> update_signal_type;
+ typedef update_signal_type::slot_type update_slot_type;
+
+ future_body_untyped_base()
+ {
+ }
+ virtual ~future_body_untyped_base()
+ {
+ }
+ virtual bool ready() const = 0;
+ virtual void join() const = 0;
+ virtual bool timed_join(const boost::system_time &absolute_time) const = 0;
+ virtual void cancel(const poet::exception_ptr &) = 0;
+ virtual exception_ptr get_exception_ptr() const = 0;
+ virtual waiter_event_queue& waiter_callbacks() const = 0;
+ boost::signals2::connection connectUpdate(const update_signal_type::slot_type &slot)
+ {
+ return _updateSignal.connect(slot);
+ }
+ boost::mutex & mutex() const
+ {
+ return _mutex;
+ }
+ boost::condition & condition() const
+ {
+ return _condition;
+ }
+ protected:
+ update_signal_type _updateSignal;
+ mutable poet::exception_ptr _exception;
+ private:
+ mutable boost::mutex _mutex;
+ mutable boost::condition _condition;
+ };
+
+ template <typename T> class future_body_base: public virtual future_body_untyped_base
+ {
+ public:
+ virtual const typename nonvoid<T>::type& getValue() const = 0;
+ virtual void setValue(const typename nonvoid<T>::type &value) = 0;
+ };
+
+ template <typename T> class future_body: public future_body_base<T>
+ {
+ public:
+ static boost::shared_ptr<future_body> create()
+ {
+ boost::shared_ptr<future_body> new_object(new future_body);
+ new_object->_waiter_callbacks.set_owner(new_object);
+ return new_object;
+ }
+ static boost::shared_ptr<future_body> create(const T &value)
+ {
+ boost::shared_ptr<future_body> new_object(new future_body(value));
+ new_object->_waiter_callbacks.set_owner(new_object);
+ return new_object;
+ }
+
+ virtual ~future_body() {}
+ virtual void setValue(const T &value)
+ {
+ bool emit_signal = false;
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ if(this->_exception == false && !_value)
+ {
+ _value = value;
+ this->condition().notify_all();
+ emit_signal = true;
+ clear_dependencies();
+ }
+ }
+ if(emit_signal)
+ {
+ this->_updateSignal();
+ }
+ }
+ virtual bool ready() const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ return _value;
+ }
+ virtual const T& getValue() const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ this->condition().wait(lock, boost::bind(&future_body<T>::check_if_complete, this, &lock));
+ if(this->_exception)
+ {
+ rethrow_exception(this->_exception);
+ }
+ BOOST_ASSERT(_value);
+ return _value.get();
+ }
+ virtual void join() const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ this->condition().wait(lock, boost::bind(&future_body<T>::check_if_complete, this, &lock));
+ if(this->_exception)
+ {
+ rethrow_exception(this->_exception);
+ }
+ BOOST_ASSERT(_value);
+ }
+ virtual bool timed_join(const boost::system_time &absolute_time) const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ return this->condition().timed_wait(lock, absolute_time, boost::bind(&future_body<T>::check_if_complete, this, &lock));
+ }
+ virtual void cancel(const poet::exception_ptr &exp)
+ {
+ bool emitSignal = false;
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ if(this->_exception == false && !_value)
+ {
+ emitSignal = true;
+ this->condition().notify_all();
+ this->_exception = exp;
+ clear_dependencies();
+ }
+ }
+ if(emitSignal)
+ {
+ this->_updateSignal();
+ }
+ }
+ virtual exception_ptr get_exception_ptr() const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ return this->_exception;
+ }
+ virtual waiter_event_queue& waiter_callbacks() const
+ {
+ return _waiter_callbacks;
+ }
+ void add_dependency(const boost::shared_ptr<void> &dependency)
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ if(_value || this->_exception) return;
+ _dependencies.push_back(dependency);
+ }
+ private:
+ future_body(): _waiter_callbacks(future_body_untyped_base::mutex(), future_body_untyped_base::condition())
+ {}
+ future_body(const T &value): _value(value),
+ _waiter_callbacks(future_body_untyped_base::mutex(), future_body_untyped_base::condition())
+ {}
+
+ bool check_if_complete(boost::unique_lock<boost::mutex> *lock) const
+ {
+ // do initial check to make sure we don't run any wait callbacks if we are already complete
+ const bool complete = _value || this->_exception;
+ if(complete) return complete;
+
+ lock->unlock();
+ _waiter_callbacks.poll();
+ lock->lock();
+ return _value || this->_exception;
+ }
+ void clear_dependencies()
+ {
+ std::vector<boost::shared_ptr<void> >().swap(_dependencies);
+ _waiter_callbacks.close_posting();
+ }
+
+ boost::optional<T> _value;
+ mutable waiter_event_queue _waiter_callbacks;
+ std::vector<boost::shared_ptr<void> > _dependencies;
+ };
+
+ template<typename ProxyType, typename ActualType>
+ static ProxyType default_conversion_function(const ActualType& actualValue)
+ {
+ return ProxyType(actualValue);
+ }
+ template<typename ActualType>
+ static null_type null_conversion_function(const ActualType& actualValue)
+ {
+ return null_type();
+ }
+
+ /* class which monitors another future_body_base<ActualType>, while returning values of type ProxyType.
+ Allows for implicit and explicit conversions between Futures with different template types.
+ */
+ template <typename ProxyType, typename ActualType> class future_body_proxy:
+ public future_body_base<ProxyType>
+ {
+ public:
+ // static factory function
+ static boost::shared_ptr<future_body_proxy> create(
+ const boost::shared_ptr<future_body_base<ActualType> > &actualFutureBody,
+ const boost::function<ProxyType (const ActualType&)> &conversionFunction)
+ {
+ boost::shared_ptr<future_body_proxy> new_object(new future_body_proxy(actualFutureBody, conversionFunction));
+
+ new_object->_waiter_callbacks.set_owner(new_object);
+
+ typedef typename future_body_untyped_base::update_slot_type slot_type;
+ slot_type update_slot(&future_body_proxy::handle_actual_body_complete, new_object.get());
+ update_slot.track(new_object);
+ boost::signals2::connection conn;
+ conn = new_object->_actualFutureBody->connectUpdate(update_slot);
+ if(actualFutureBody->ready() || actualFutureBody->get_exception_ptr())
+ {
+ try
+ {
+ update_slot();
+ }
+ catch(const boost::signals2::expired_slot &)
+ {
+ conn.disconnect();
+ }
+ /* we don't need to bother observing actualFutureBody's waiter_event_queue
+ if it was already complete */
+ return new_object;
+ }
+
+ new_object->waiter_callbacks().observe(actualFutureBody->waiter_callbacks());
+
+ return new_object;
+ }
+ virtual void setValue(const ProxyType &value)
+ {
+ BOOST_ASSERT(false);
+ }
+ virtual bool ready() const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ return _proxyValue;
+ }
+ virtual const ProxyType& getValue() const
+ {
+ _actualFutureBody->join();
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ this->condition().wait(lock, boost::bind(&future_body_proxy::check_if_complete, this, &lock));
+ if(this->_exception) rethrow_exception(this->_exception);
+ BOOST_ASSERT(_proxyValue);
+ return _proxyValue.get();
+ }
+ virtual void join() const
+ {
+ _actualFutureBody->join();
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ this->condition().wait(lock, boost::bind(&future_body_proxy::check_if_complete, this, &lock));
+ }
+ virtual bool timed_join(const boost::system_time &absolute_time) const
+ {
+ if(_actualFutureBody->timed_join(absolute_time) == false) return false;
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ return this->condition().timed_wait(lock, absolute_time, boost::bind(&future_body_proxy::check_if_complete, this, &lock));
+ }
+ virtual void cancel(const poet::exception_ptr &exp)
+ {
+ _actualFutureBody->cancel(exp);
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ this->condition().notify_all();
+ }
+ virtual exception_ptr get_exception_ptr() const
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ return this->_exception;
+ }
+ virtual waiter_event_queue& waiter_callbacks() const
+ {
+ return _waiter_callbacks;
+ }
+ private:
+ future_body_proxy(boost::shared_ptr<future_body_base<ActualType> > actualFutureBody,
+ const boost::function<ProxyType (const ActualType&)> &conversionFunction):
+ _actualFutureBody(actualFutureBody),
+ _conversionFunction(conversionFunction),
+ _waiter_callbacks(future_body_untyped_base::mutex(), future_body_untyped_base::condition()),
+ _conversionEventPosted(false)
+ {}
+
+ void waiter_event()
+ {
+ boost::optional<ProxyType> value;
+ try
+ {
+ value = _conversionFunction(_actualFutureBody->getValue());
+ }catch(...)
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ this->_exception = current_exception();
+ }
+ this->_updateSignal();
+ return;
+ }
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ BOOST_ASSERT(!_proxyValue);
+ _proxyValue = value;
+ }
+ this->_updateSignal();
+ }
+ void handle_actual_body_complete()
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ if(_conversionEventPosted) return;
+ _conversionEventPosted = true;
+ }
+ _waiter_callbacks.post(boost::bind(&future_body_proxy::waiter_event, this));
+ _waiter_callbacks.close_posting();
+ throw boost::signals2::expired_slot();
+ }
+ bool check_if_complete(boost::unique_lock<boost::mutex> *lock) const
+ {
+ // do initial check to make sure we don't run any wait callbacks if we are already complete
+ const bool complete = _proxyValue || this->_exception;
+ if(complete) return complete;
+
+ lock->unlock();
+ _waiter_callbacks.poll();
+ lock->lock();
+ return _proxyValue || this->_exception;
+ }
+
+ boost::shared_ptr<future_body_base<ActualType> > _actualFutureBody;
+ boost::function<ProxyType (const ActualType&)> _conversionFunction;
+ mutable boost::optional<ProxyType> _proxyValue;
+ mutable waiter_event_queue _waiter_callbacks;
+ mutable bool _conversionEventPosted;
+ };
+
+ class promise_body_untyped_base
+ {
+ public:
+ virtual ~promise_body_untyped_base()
+ {}
+ virtual void renege(const exception_ptr &exp) = 0;
+ virtual bool has_future() const = 0;
+ virtual boost::shared_ptr<future_body_untyped_base> shared_future_body() const = 0;
+ };
+
+ template <typename T> class promise_body: public promise_body_untyped_base
+ {
+ public:
+ promise_body(): _future_body(future_body<T>::create())
+ {}
+ ~promise_body()
+ {
+ renege(copy_exception(uncertain_future()));
+ }
+
+ void fulfill(const T &value)
+ {
+ _future_body->setValue(value);
+ }
+ void future_fulfill(const future<T> &future_value)
+ {
+ typedef typename future_body_untyped_base::update_slot_type slot_type;
+ slot_type update_slot(&promise_body::handle_future_fulfillment,
+ _future_body.get(), get_future_body(future_value).get());
+ update_slot.track(_future_body);
+ update_slot.track(get_future_body(future_value));
+ future_fulfill_guts(get_future_body(future_value), update_slot);
+ }
+
+ // provided for promise<void>
+ void future_void_fulfill(const future<void> &future_value)
+ {
+ typedef typename future_body_untyped_base::update_slot_type slot_type;
+ slot_type update_slot(&promise_body::handle_future_void_fulfillment,
+ _future_body.get(), get_future_body(future_value).get());
+ update_slot.track(_future_body);
+ update_slot.track(get_future_body(future_value));
+ future_fulfill_guts(get_future_body(future_value), update_slot);
+ }
+
+ virtual void renege(const exception_ptr &exp)
+ {
+ _future_body->cancel(exp);
+ }
+ virtual bool has_future() const
+ {
+ return !_future_body.unique();
+ }
+ virtual boost::shared_ptr<future_body_untyped_base> shared_future_body() const
+ {
+ return _future_body;
+ }
+
+ boost::shared_ptr<future_body<T> > _future_body;
+ private:
+ template<typename U>
+ void future_fulfill_guts(const boost::shared_ptr<U> &fulfiller_body,
+ const future_body_untyped_base::update_slot_type &update_slot)
+ {
+ boost::signals2::connection conn;
+ conn = fulfiller_body->connectUpdate(update_slot);
+ if(fulfiller_body->ready() || fulfiller_body->get_exception_ptr())
+ {
+ try
+ {
+ update_slot();
+ }
+ catch(const boost::signals2::expired_slot &)
+ {
+ conn.disconnect();
+ }
+ /* if fulfiller_body was already complete, we are finished. */
+ return;
+ }
+
+ _future_body->waiter_callbacks().observe(fulfiller_body->waiter_callbacks());
+
+ // stick shared_ptr to future_value in dependent _future_body
+ _future_body->add_dependency(fulfiller_body);
+ }
+ inline static void handle_future_fulfillment(future_body_base<T> *fulfillee,
+ future_body_base<T> *fulfiller);
+ inline static void handle_future_void_fulfillment(future_body_base<nonvoid<void>::type> *fulfillee,
+ future_body_untyped_base *fulfiller);
+ };
+
+ template<typename T>
+ future<T> create_future(const boost::shared_ptr<future_body_untyped_base> &body);
+ template<>
+ future<void> create_future<void>(const boost::shared_ptr<future_body_untyped_base> &body);
+ } // namespace detail
+
+ template <typename T>
+ class promise
+ {
+ template <typename U>
+ friend class future;
+ template <typename U>
+ friend class promise;
+ friend class promise<void>;
+ public:
+ typedef T value_type;
+ promise(): _pimpl(new detail::promise_body<T>)
+ {}
+ virtual ~promise() {}
+ template<typename U>
+ void fulfill(const U &value)
+ {
+ _pimpl->fulfill(value);
+ }
+ template<typename U>
+ void fulfill(const future<U> &future_value)
+ {
+ _pimpl->future_fulfill(future_value);
+ }
+ template <typename E>
+ void renege(const E &exception)
+ {
+ _pimpl->renege(poet::copy_exception(exception));
+ }
+ void renege(const poet::exception_ptr &exp)
+ {
+ _pimpl->renege(exp);
+ }
+ bool has_future() const
+ {
+ return _pimpl->has_future();
+ }
+ void reset()
+ {
+ promise temp;
+ swap(temp);
+ }
+ void swap(promise &other)
+ {
+ using std::swap;
+ swap(_pimpl, other._pimpl);
+ }
+ private:
+ boost::shared_ptr<detail::promise_body<T> > _pimpl;
+ };
+
+ // void specialization
+ template<>
+ class promise<void>
+ {
+ template <typename U>
+ friend class future;
+ template <typename U>
+ friend class promise;
+ public:
+ typedef void value_type;
+
+ promise(): _pimpl(new detail::promise_body<detail::nonvoid<void>::type>)
+ {}
+ // allow conversion from a promise with any template type to a promise<void>
+ template <typename OtherType>
+ promise(const promise<OtherType> &other): _pimpl(other._pimpl)
+ {}
+ virtual ~promise() {}
+ void fulfill()
+ {
+ downcast_pimpl()->fulfill(detail::nonvoid<void>::type());
+ }
+ void fulfill(const future<void> &future_value)
+ {
+ downcast_pimpl()->future_void_fulfill(future_value);
+ }
+ template <typename E>
+ void renege(const E &exception)
+ {
+ _pimpl->renege(poet::copy_exception(exception));
+ }
+ void renege(const poet::exception_ptr &exp)
+ {
+ _pimpl->renege(exp);
+ }
+ bool has_future() const
+ {
+ return _pimpl->has_future();
+ }
+ void reset()
+ {
+ promise temp;
+ swap(temp);
+ }
+ void swap(promise &other)
+ {
+ using std::swap;
+ swap(_pimpl, other._pimpl);
+ }
+ private:
+ boost::shared_ptr<detail::promise_body<detail::nonvoid<void>::type> > downcast_pimpl() const
+ {
+ using boost::dynamic_pointer_cast;
+ boost::shared_ptr<detail::promise_body<detail::nonvoid<void>::type> > downcast =
+ dynamic_pointer_cast<detail::promise_body<detail::nonvoid<void>::type> >(_pimpl);
+ if(downcast == false)
+ {
+ throw std::invalid_argument("Cannot fulfill a promise<T> for non-void T through a promise<void>");
+ }
+ return downcast;
+ }
+
+ boost::shared_ptr<detail::promise_body_untyped_base> _pimpl;
+ };
+
+ template<typename T>
+ void swap(promise<T> &a, promise<T> &b)
+ {
+ a.swap(b);
+ }
+
+ template <typename T> class future
+ {
+ friend future<T> detail::create_future<T>(const boost::shared_ptr<detail::future_body_untyped_base> &body);
+ friend const boost::shared_ptr<typename detail::nonvoid_future_body_base<T>::type>& detail::get_future_body<T>(const poet::future<T> &f);
+
+ typedef boost::shared_ptr<detail::future_body_base<T> > future_body_type;
+ public:
+ template <typename OtherType> friend class future;
+ friend class future<void>;
+
+ typedef T value_type;
+
+ future(const promise<T> &promise): _future_body(promise._pimpl->_future_body)
+ {}
+ template <typename OtherType>
+ future(const promise<OtherType> &promise)
+ {
+ future<OtherType> other_future(promise);
+ *this = other_future;
+ }
+ future(const T &value): _future_body(detail::future_body<T>::create(value))
+ {}
+ template <typename OtherType> future(const future<OtherType> &other)
+ {
+ BOOST_ASSERT(typeid(T) != typeid(OtherType));
+ if(other._future_body == 0)
+ {
+ _future_body.reset();
+ return;
+ }
+ boost::function<T (const OtherType&)> typedConversionFunction =
+ boost::bind(&detail::default_conversion_function<T, OtherType>, _1);
+ _future_body = detail::future_body_proxy<T, OtherType>::create(
+ other._future_body, typedConversionFunction);
+ }
+ template <typename OtherType>
+ future(const OtherType &other): _future_body(detail::future_body<T>::create(other))
+ {}
+ future()
+ {}
+ virtual ~future() {}
+ bool ready() const
+ {
+ if(_future_body == 0) return false;
+ bool result = _future_body->ready();
+ if(result == true) return result;
+ _future_body->waiter_callbacks().poll();
+ return _future_body->ready();
+ }
+ const T& get() const
+ {
+ if(_future_body == 0)
+ {
+ throw uncertain_future();
+ }
+ return _future_body->getValue();
+ }
+ operator const T&() const
+ {
+ return get();
+ }
+ void join() const
+ {
+ if(_future_body == 0)
+ {
+ return;
+ }
+ _future_body->join();
+ }
+ bool timed_join(const boost::system_time &absolute_time) const
+ {
+ if(_future_body == false) return true;
+ return _future_body->timed_join(absolute_time);
+ }
+ template <typename OtherType> const future<T>& operator=(const future<OtherType> &other)
+ {
+ BOOST_ASSERT(typeid(T) != typeid(OtherType));
+ _future_body = detail::future_body_proxy<T, OtherType>::create(other._future_body);
+ return *this;
+ }
+ bool has_exception() const
+ {
+ if(_future_body == 0) return true;
+ bool result = _future_body->get_exception_ptr();
+ if(result == true) return result;
+ _future_body->waiter_callbacks().poll();
+ return _future_body->get_exception_ptr();
+ }
+ void swap(future &other)
+ {
+ using std::swap;
+ swap(_future_body, other._future_body);
+ }
+ private:
+ future(const boost::shared_ptr<detail::future_body_base<T> > &future_body):_future_body(future_body)
+ {}
+
+ future_body_type _future_body;
+ };
+
+ template <>
+ class future<void>
+ {
+ friend future<void> detail::create_future<void>(const boost::shared_ptr<detail::future_body_untyped_base> &body);
+ friend const boost::shared_ptr<detail::nonvoid_future_body_base<void>::type>& detail::get_future_body<void>(const poet::future<void> &f);
+
+ typedef boost::shared_ptr<detail::future_body_untyped_base > future_body_type;
+ public:
+ template <typename OtherType> friend class future;
+ friend class promise<void>;
+
+ typedef void value_type;
+
+ future(const promise<void> &promise): _future_body(promise._pimpl->shared_future_body())
+ {}
+ template <typename OtherType>
+ future(const promise<OtherType> &promise)
+ {
+ future<OtherType> other_future(promise);
+ *this = other_future;
+ }
+ template <typename OtherType> future(const future<OtherType> &other)
+ {
+ BOOST_ASSERT(typeid(void) != typeid(OtherType));
+ if(other._future_body == 0)
+ {
+ _future_body.reset();
+ return;
+ }
+ _future_body = other._future_body;
+ }
+ future()
+ {}
+ virtual ~future() {}
+ void get() const
+ {
+ if(_future_body == 0)
+ {
+ throw uncertain_future();
+ }
+ _future_body->join();
+ exception_ptr ep = _future_body->get_exception_ptr();
+ if(ep) rethrow_exception(ep);
+ }
+ operator void () const
+ {
+ get();
+ }
+ template <typename OtherType> const future<void>& operator=(const future<OtherType> &other)
+ {
+ BOOST_ASSERT(typeid(void) != typeid(OtherType));
+ _future_body = other._future_body;
+ return *this;
+ }
+ void join() const
+ {
+ if(_future_body == 0)
+ {
+ return;
+ }
+ _future_body->join();
+ }
+ bool timed_join(const boost::system_time &absolute_time) const
+ {
+ if(_future_body == 0)
+ {
+ return true;
+ }
+ return _future_body->timed_join(absolute_time);
+ }
+ bool ready() const
+ {
+ if(_future_body == 0) return false;
+ _future_body->waiter_callbacks().poll();
+ return _future_body->ready();
+ }
+ bool has_exception() const
+ {
+ if(_future_body == 0) return true;
+ _future_body->waiter_callbacks().poll();
+ return _future_body->get_exception_ptr();
+ }
+ void swap(future &other)
+ {
+ using std::swap;
+ swap(_future_body, other._future_body);
+ }
+ private:
+ future(const boost::shared_ptr<detail::future_body_untyped_base > &future_body):_future_body(future_body)
+ {}
+
+ future_body_type _future_body;
+ };
+
+ template<typename T>
+ void swap(future<T> &a, future<T> &b)
+ {
+ a.swap(b);
+ }
+
+ namespace detail
+ {
+ template<typename T>
+ void promise_body<T>::handle_future_fulfillment(future_body_base<T> *fulfillee,
+ future_body_base<T> *fulfiller)
+ {
+ try
+ {
+ fulfillee->setValue(fulfiller->getValue());
+ }
+ catch(...)
+ {
+ fulfillee->cancel(current_exception());
+ }
+ throw boost::signals2::expired_slot();
+ }
+ template <typename T>
+ void promise_body<T>::handle_future_void_fulfillment(future_body_base<nonvoid<void>::type> * fulfillee,
+ future_body_untyped_base * fulfiller)
+ {
+ exception_ptr ep = fulfiller->get_exception_ptr();
+ if(ep)
+ {
+ fulfillee->cancel(ep);
+ }else
+ {
+ BOOST_ASSERT(fulfiller->ready());
+ fulfillee->setValue(null_type());
+ }
+ throw boost::signals2::expired_slot();
+ }
+
+ template<typename T>
+ future<T> create_future(const boost::shared_ptr<future_body_untyped_base> &body)
+ {
+ using boost::dynamic_pointer_cast;
+ return future<T>(dynamic_pointer_cast<future_body_base<T> >(body));
+ }
+ template<>
+ inline future<void> create_future<void>(const boost::shared_ptr<future_body_untyped_base> &body)
+ {
+ return future<void>(body);
+ }
+
+ template<typename T>
+ class shared_uncertain_future_body
+ {
+ public:
+ static boost::shared_ptr<typename nonvoid_future_body_base<T>::type> value;
+ private:
+ static boost::shared_ptr<typename nonvoid_future_body_base<T>::type> create()
+ {
+ boost::shared_ptr<typename nonvoid_future_body_base<T>::type> new_object(
+ future_body<typename nonvoid<T>::type>::create());
+ new_object->cancel(copy_exception(uncertain_future()));
+ return new_object;
+ }
+ };
+ template<typename T>
+ boost::shared_ptr<typename nonvoid_future_body_base<T>::type>
+ shared_uncertain_future_body<T>::value(shared_uncertain_future_body<T>::create());
+
+ template<typename T>
+ const boost::shared_ptr<typename nonvoid_future_body_base<T>::type>& get_future_body(const poet::future<T> &f)
+ {
+ if(!f._future_body) return shared_uncertain_future_body<T>::value;
+ return f._future_body;
+ }
+ } // namespace detail
+}
+
+
+#endif // _POET_FUTURE_H
Added: sandbox/libpoet/trunk/poet/future_barrier.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/future_barrier.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,408 @@
+/*
+ Provides future_barrier and future_combining_barrier free factory functions,
+ which create composite futures which becomes ready based on the states of
+ a group of input futures. A future returned by future_barrier becomes
+ ready when all of the input futures become ready or have exceptions.
+ The future_combining_barrier allows a return value to be generated
+ from the values of the input futures via a user supplied "Combiner"
+ function.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-20
+*/
+
+// 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 _POET_FUTURE_BARRIER_HPP
+#define _POET_FUTURE_BARRIER_HPP
+
+#include <boost/config.hpp>
+#include <boost/function.hpp>
+#include <boost/noncopyable.hpp>
+#include <boost/optional.hpp>
+#include <boost/type_traits.hpp>
+#include <iterator>
+#include <poet/detail/identity.hpp>
+#include <poet/detail/nonvoid.hpp>
+#include <poet/detail/template_static.hpp>
+#include <poet/detail/utility.hpp>
+#include <poet/future.hpp>
+#include <vector>
+
+namespace poet
+{
+ namespace detail
+ {
+ template<typename Lock>
+ class scoped_unlocker
+ {
+ public:
+ scoped_unlocker(Lock &lock): _lock(lock), _owns_lock(lock.owns_lock())
+ {
+ if(_owns_lock)
+ _lock.unlock();
+ }
+ ~scoped_unlocker()
+ {
+ if(_owns_lock && _lock.owns_lock() == false)
+ _lock.lock();
+ }
+ void lock() {_lock.lock();}
+ void unlock() {_lock.unlock();}
+ private:
+ Lock &_lock;
+ bool _owns_lock;
+ };
+ template<typename Mutex>
+ class unscoped_lock
+ {
+ public:
+ unscoped_lock(Mutex &mutex): _lock(mutex, boost::adopt_lock_t())
+ {}
+ ~unscoped_lock()
+ {
+ _lock.release();
+ }
+ void lock()
+ {
+ _lock.lock();
+ }
+ void unlock()
+ {
+ _lock.unlock();
+ }
+ bool owns_lock() const
+ {
+ return _lock.owns_lock();
+ }
+ private:
+ boost::unique_lock<Mutex> _lock;
+ };
+
+ class future_barrier_body_base: public virtual future_body_untyped_base
+ {
+ public:
+ virtual bool ready() const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ return _ready;
+ }
+ virtual void join() const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ condition().wait(lock, boost::bind(&future_barrier_body_base::check_if_complete, this, &lock));
+ }
+ virtual bool timed_join(const boost::system_time &absolute_time) const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ return condition().timed_wait(lock, absolute_time, boost::bind(&future_barrier_body_base::check_if_complete, this, &lock));
+ }
+ virtual void cancel(const poet::exception_ptr&)
+ {}
+ virtual exception_ptr get_exception_ptr() const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ return _exception;
+ }
+ virtual waiter_event_queue& waiter_callbacks() const
+ {
+ return _waiter_callbacks;
+ }
+ protected:
+ typedef boost::function<exception_ptr (const exception_ptr &)> exception_handler_type;
+
+ future_barrier_body_base(const boost::function<void ()> &bound_combiner,
+ const exception_handler_type &exception_handler):
+ _waiter_callbacks(future_body_untyped_base::mutex(), future_body_untyped_base::condition()),
+ _ready_count(0), _ready(false), _bound_combiner(bound_combiner),
+ _exception_handler(exception_handler), _combiner_event_posted(false)
+ {}
+
+ template<typename U, typename FutureIterator>
+ static void init(const boost::shared_ptr<U> &owner, FutureIterator future_begin, FutureIterator future_end)
+ {
+ owner->_waiter_callbacks.set_owner(owner);
+
+ // handle special case of no dependencies
+ if(future_begin == future_end)
+ {
+ owner->_combiner_event_posted = true;
+ owner->_waiter_callbacks.post(boost::bind(&future_barrier_body_base::waiter_event, owner.get(), exception_ptr()));
+ owner->_waiter_callbacks.close_posting();
+ return;
+ }
+
+ FutureIterator it;
+ unsigned i = 0;
+ for(it = future_begin; it != future_end; ++it, ++i)
+ {
+ owner->_dependency_completes.push_back(false);
+ update_signal_type::slot_type update_slot(&future_barrier_body_base::check_dependency,
+ owner.get(), make_weak(get_future_body(*it)), i);
+ update_slot.track(owner);
+ boost::signals2::connection conn;
+ conn = get_future_body(*it)->connectUpdate(update_slot);
+ try
+ {
+ update_slot();
+ }
+ catch(const boost::signals2::expired_slot &)
+ {
+ conn.disconnect();
+ break;
+ }
+
+ owner->waiter_callbacks().observe(get_future_body(*it)->waiter_callbacks());
+ }
+ }
+ private:
+ void waiter_event(const exception_ptr &dependency_exception)
+ {
+ exception_ptr ep;
+ if(dependency_exception)
+ {
+ try
+ {
+ ep = _exception_handler(dependency_exception);
+ }catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ }else
+ {
+ try
+ {
+ _bound_combiner();
+ }catch(...)
+ {
+ ep = current_exception();
+ }
+ }
+ {
+ boost::unique_lock<boost::mutex> lock(this->mutex());
+ _exception = ep;
+ _ready = !_exception;
+ condition().notify_all();
+ }
+ this->_updateSignal();
+ }
+ void check_dependency(const boost::weak_ptr<future_body_untyped_base > &weak_dependency,
+ unsigned dependency_index)
+ {
+ boost::shared_ptr<future_body_untyped_base> dependency(weak_dependency);
+ exception_ptr dependency_exception;
+ bool all_ready = false;
+ bool received_first_exception = false;
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+
+ if(_combiner_event_posted) return;
+
+ if(_dependency_completes.at(dependency_index) == false)
+ {
+ const bool dep_ready = dependency->ready();
+ dependency_exception = dependency->get_exception_ptr();
+ if(dependency_exception && _exception == false)
+ {
+ _dependency_completes.at(dependency_index) = true;
+ received_first_exception = true;
+ _combiner_event_posted = true;
+ }
+ if(dep_ready)
+ {
+ _dependency_completes.at(dependency_index) = true;
+ _ready_count += dep_ready;
+ if(_ready_count == _dependency_completes.size())
+ {
+ all_ready = true;
+ _combiner_event_posted = true;
+ }
+ }
+ }
+ }
+ if(all_ready || received_first_exception)
+ {
+ _waiter_callbacks.post(boost::bind(&future_barrier_body_base::waiter_event, this, dependency_exception));
+ _waiter_callbacks.close_posting();
+ throw boost::signals2::expired_slot();
+ }
+ }
+ bool check_if_complete(boost::unique_lock<boost::mutex> *lock) const
+ {
+ // do initial check to make sure we don't run any wait callbacks if we are already complete
+ const bool complete = _ready || _exception;
+ if(complete) return complete;
+
+ lock->unlock();
+ _waiter_callbacks.poll();
+ lock->lock();
+ return _ready || _exception;
+ }
+
+ mutable waiter_event_queue _waiter_callbacks;
+ mutable std::vector<bool> _dependency_completes;
+ mutable unsigned _ready_count;
+ mutable bool _ready;
+ mutable boost::function<void ()> _bound_combiner;
+ mutable exception_handler_type _exception_handler;
+ mutable bool _combiner_event_posted;
+ };
+
+ template<typename T>
+ const typename nonvoid<T>::type& nonvoid_future_get(const future<T> &f)
+ {
+ return f.get();
+ }
+ template<>
+ inline const nonvoid<void>::type& nonvoid_future_get<void>(const future<void> &f)
+ {
+ return template_static<nonvoid<void>, nonvoid<void>::type>::object;
+ }
+
+ template<typename R, typename Combiner, typename T>
+ class combiner_invoker
+ {
+ public:
+ combiner_invoker(const Combiner &combiner):
+ _combiner(combiner)
+ {}
+ template<typename InputFutureIterator>
+ void operator()(boost::optional<R> &result, InputFutureIterator begin, InputFutureIterator end)
+ {
+ std::vector<typename nonvoid<T>::type> input_values;
+ std::transform(begin, end, std::back_inserter(input_values),
+ &nonvoid_future_get<T>);
+ result = _combiner(input_values.begin(), input_values.end());
+ }
+ private:
+ Combiner _combiner;
+ };
+ template<typename Combiner, typename T>
+ class combiner_invoker<void, Combiner, T>
+ {
+ public:
+ combiner_invoker(const Combiner &combiner):
+ _combiner(combiner)
+ {}
+ template<typename InputFutureIterator>
+ void operator()(boost::optional<nonvoid<void>::type> &result, InputFutureIterator begin, InputFutureIterator end)
+ {
+ std::vector<typename nonvoid<T>::type> input_values;
+ std::transform(begin, end, std::back_inserter(input_values),
+ &nonvoid_future_get<T>);
+ _combiner(input_values.begin(), input_values.end());
+ result = null_type();
+ }
+ private:
+ Combiner _combiner;
+ };
+
+ /* future_body for futures returned by future_barrier. Becomes ready
+ only when all the futures on its list have become ready (or have exceptions)
+ */
+ template<typename R, typename Combiner, typename T>
+ class future_barrier_body:
+ public future_body_base<R>, public future_barrier_body_base
+ {
+ typedef future_barrier_body_base barrier_base_class;
+ public:
+ template<typename InputFutureIterator>
+ static boost::shared_ptr<future_barrier_body> create(const Combiner &combiner,
+ const barrier_base_class::exception_handler_type &exception_handler,
+ InputFutureIterator future_begin, InputFutureIterator future_end)
+ {
+ boost::shared_ptr<future_barrier_body> new_object(new future_barrier_body(combiner, exception_handler,
+ future_begin, future_end));
+ barrier_base_class::init(new_object, new_object->_input_futures.begin(), new_object->_input_futures.end());
+ return new_object;
+ }
+ using barrier_base_class::ready;
+ using barrier_base_class::join;
+ using barrier_base_class::timed_join;
+ using barrier_base_class::cancel;
+ using barrier_base_class::get_exception_ptr;
+ virtual const typename nonvoid<R>::type& getValue() const
+ {
+ this->join();
+ if(this->_exception)
+ {
+ rethrow_exception(this->_exception);
+ }
+ return *this->_combiner_result;
+ }
+ virtual void setValue(const typename nonvoid<R>::type &value)
+ {
+ BOOST_ASSERT(false);
+ }
+ private:
+ template<typename InputFutureIterator>
+ future_barrier_body(const Combiner &combiner,
+ const barrier_base_class::exception_handler_type &exception_handler,
+ InputFutureIterator future_begin, InputFutureIterator future_end):
+#ifdef BOOST_MSVC
+#pragma warning( suppress : 4355 ) // suppress msvc 9 warning
+#endif
+ barrier_base_class(boost::bind(&future_barrier_body::invoke_combiner, this), exception_handler),
+ _input_futures(future_begin, future_end),
+ _combiner_invoker(combiner)
+ {}
+
+ void invoke_combiner()
+ {
+ boost::optional<typename nonvoid<R>::type> result;
+ _combiner_invoker(result, _input_futures.begin(), _input_futures.end());
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ _combiner_result = result;
+ }
+ }
+
+ std::vector<future<T> > _input_futures;
+ combiner_invoker<R, Combiner, T> _combiner_invoker;
+ boost::optional<typename nonvoid<R>::type> _combiner_result;
+#ifdef BOOST_MSVC
+#pragma warning( suppress : 4250 ) // suppress msvc 9 warning
+#endif
+ };
+
+ class null_void_combiner
+ {
+ public:
+ typedef void result_type;
+ template<typename Iterator>
+ result_type operator()(Iterator, Iterator)
+ {}
+ };
+ } // namespace detail
+
+ template<typename InputIterator>
+ future<void> future_barrier_range(InputIterator future_begin, InputIterator future_end)
+ {
+ typedef detail::future_barrier_body<void, detail::null_void_combiner, void> body_type;
+ future<void> result = detail::create_future<void>(body_type::create(detail::null_void_combiner(), detail::identity(),
+ future_begin, future_end));
+ return result;
+ }
+
+ template<typename R, typename Combiner, typename ExceptionHandler, typename InputIterator>
+ future<R> future_combining_barrier_range(const Combiner &combiner, const ExceptionHandler &exception_handler,
+ InputIterator future_begin, InputIterator future_end)
+ {
+ typedef typename std::iterator_traits<InputIterator>::value_type input_future_type;
+ typedef typename input_future_type::value_type input_value_type;
+ typedef detail::future_barrier_body<R, Combiner, input_value_type> body_type;
+ future<R> result = detail::create_future<R>(body_type::create(combiner, exception_handler, future_begin, future_end));
+ return result;
+ }
+}
+
+#ifndef POET_FUTURE_BARRIER_MAX_ARGS
+#define POET_FUTURE_BARRIER_MAX_ARGS 10
+#endif
+
+#define BOOST_PP_ITERATION_LIMITS (1, POET_FUTURE_BARRIER_MAX_ARGS)
+#define BOOST_PP_FILENAME_1 <poet/detail/future_barrier_template.hpp>
+#include BOOST_PP_ITERATE()
+
+#endif // _POET_FUTURE_BARRIER_HPP
Added: sandbox/libpoet/trunk/poet/future_select.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/future_select.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,524 @@
+/*
+ Provides future_select free functions, which allow
+ creation of a future which becomes ready based on the states of
+ a group of input futures. A future returned by future_select
+ becomes ready when any one
+ of the input futures becomes ready or has an exception.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-20
+*/
+
+// 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 _POET_FUTURE_SELECT_HPP
+#define _POET_FUTURE_SELECT_HPP
+
+#include <boost/bind.hpp>
+#include <boost/config.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include <cstddef>
+#include <iterator>
+#include <poet/future.hpp>
+#include <poet/detail/nonvoid.hpp>
+#include <poet/detail/utility.hpp>
+#include <deque>
+#include <list>
+
+namespace poet
+{
+ template<typename R, typename Combiner, typename T1>
+ future<R> future_combining_barrier(const Combiner &combiner, const future<T1> &f1);
+
+ namespace detail
+ {
+ template<typename T>
+ const typename nonvoid<T>::type& nonvoid_future_body_get(const future_body_base<T> &body)
+ {
+ return body.getValue();
+ }
+ inline const nonvoid<void>::type& nonvoid_future_body_get(const future_body_untyped_base &body)
+ {
+ return template_static<nonvoid<void>, nonvoid<void>::type>::object;
+ }
+
+ template<typename T>
+ class future_selector_body: public boost::enable_shared_from_this<future_selector_body<T> >
+ {
+ typedef std::list<boost::shared_ptr<typename nonvoid_future_body_base<T>::type> > dependencies_type;
+ typedef future_body<typename nonvoid<T>::type> dependent_type;
+ typedef std::deque<boost::weak_ptr<dependent_type> > selected_container_type;
+ typedef std::deque<boost::shared_ptr<dependent_type> > fulfilled_container_type;
+ struct dependency_eraser_info
+ {
+ dependency_eraser_info(): iterator_valid(false)
+ {}
+ boost::signals2::connection waiter_connection;
+ typename dependencies_type::iterator iterator;
+ bool iterator_valid;
+ };
+ public:
+ static boost::shared_ptr<future_selector_body> create()
+ {
+ boost::shared_ptr<future_selector_body> new_object(new future_selector_body);
+ new_object->_waiter_callbacks.set_owner(new_object);
+ new_object->pop_selected();
+ return new_object;
+ }
+ boost::shared_ptr<future_selector_body> clone() const
+ {
+ boost::shared_ptr<future_selector_body> new_object(new future_selector_body(*this));
+ new_object->_waiter_callbacks.set_owner(new_object);
+ typename dependencies_type::iterator it;
+ for(it = new_object->_dependencies.begin(); it != new_object->_dependencies.end(); ++it)
+ {
+ new_object->connect_to_dependency(it);
+ }
+ return new_object;
+ }
+ void push(const future<T> &f)
+ {
+ const boost::shared_ptr<typename nonvoid_future_body_base<T>::type> body = get_future_body(f);
+ const boost::shared_ptr<dependency_eraser_info> eraser_info(new dependency_eraser_info);
+ typename dependencies_type::iterator dep_it;
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+
+ dep_it = _dependencies.insert(_dependencies.end(), body);
+ ++_dependencies_size;
+ }
+ connect_to_dependency(dep_it);
+ }
+ future<T> selected() const
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ return create_future<T>(_selected);
+ }
+ void pop_selected()
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ if(_fulfilled_promises.empty())
+ {
+ lock.unlock();
+
+ boost::shared_ptr<dependent_type> dependent = dependent_type::create();
+ dependent->waiter_callbacks().observe(_waiter_callbacks);
+
+ /* stick a shared_ptr that owns this onto the dependent so it will keep us alive
+ as long as it needs us. */
+ dependent->add_dependency(this->shared_from_this());
+
+ lock.lock();
+ _selected = dependent;
+ _selected_promises.push_back(dependent);
+ }else
+ {
+ _selected = _fulfilled_promises.front();
+ _fulfilled_promises.pop_front();
+ }
+ }
+ std::ptrdiff_t size() const
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ return _dependencies_size +_fulfilled_promises.size() - _selected_promises.size() + 1;
+ }
+ /* detach means the user isn't going to call push or pop_selected any more,
+ since future_selector object has destructed. So cancel futures that
+ cannot possibly complete otherwise. */
+ void detach()
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ const int extra_selected = _selected_promises.size() - _dependencies_size;
+ int i;
+ boost::shared_ptr<dependent_type> dependent;
+ for(i = 0; i < extra_selected; ++i)
+ {
+ dependent = _selected_promises.back().lock();
+ if(dependent) dependent->cancel(copy_exception(uncertain_future()));
+ _selected_promises.pop_back();
+ }
+
+ _selected.reset();
+ _fulfilled_promises.clear();
+ }
+ private:
+ future_selector_body():
+ _waiter_callbacks(_mutex, _condition), _dependencies_size(0)
+ {
+ }
+ future_selector_body(const future_selector_body &other):
+ _waiter_callbacks(_mutex, _condition)
+ {
+ boost::unique_lock<boost::mutex> lock(other._mutex);
+
+ /* _selected_promises in new_object should have same size as original,
+ but only has expired weak_ptr, since the original will handle fulfilling
+ the its real _selected_promises. */
+ _selected_promises.resize(other._selected_promises.size());
+ _selected = other._selected;
+ _fulfilled_promises = other._fulfilled_promises;
+ _dependencies = other._dependencies;
+ _dependencies_size = other._dependencies_size;
+ }
+ void wait_event(typename dependencies_type::iterator completed_dependency)
+ {
+ boost::shared_ptr<typename nonvoid_future_body_base<T>::type> dependency;
+ boost::shared_ptr<dependent_type> fulfilled_promise;
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ if(_selected_promises.empty())
+ {
+ fulfilled_promise = dependent_type::create();
+ _fulfilled_promises.push_back(fulfilled_promise);
+ }else
+ {
+ fulfilled_promise = _selected_promises.front().lock();
+ _selected_promises.pop_front();
+ }
+ dependency = *completed_dependency;
+ _dependencies.erase(completed_dependency);
+ --_dependencies_size;
+ }
+ if(fulfilled_promise == false) return;
+
+ const bool dep_ready = dependency->ready();
+
+ if(dep_ready)
+ {
+ fulfilled_promise->setValue(nonvoid_future_body_get(*dependency));
+ }else
+ {
+ exception_ptr ep = dependency->get_exception_ptr();
+ fulfilled_promise->cancel(ep);
+ }
+ }
+ void check_dependency(const boost::weak_ptr<typename nonvoid_future_body_base<T>::type> &weak_dependency,
+ const boost::shared_ptr<dependency_eraser_info> &dependency_eraser_info)
+ {
+ boost::shared_ptr<typename nonvoid_future_body_base<T>::type> dependency = weak_dependency.lock();
+ if(!dependency)
+ {
+ throw boost::signals2::expired_slot();
+ }
+
+ const bool dep_ready = dependency->ready();
+ exception_ptr ep;
+
+ if(!dep_ready) ep = dependency->get_exception_ptr();
+
+ if(dep_ready || ep)
+ {
+ {
+ boost::unique_lock<boost::mutex> lock(_mutex);
+ if(dependency_eraser_info->iterator_valid == false)
+ {
+ throw boost::signals2::expired_slot();
+ }
+ dependency_eraser_info->iterator_valid = false;
+ dependency_eraser_info->waiter_connection.disconnect();
+ }
+ _waiter_callbacks.post(boost::bind(&future_selector_body::wait_event, this, dependency_eraser_info->iterator));
+ throw boost::signals2::expired_slot();
+ }
+ }
+ void connect_to_dependency(typename dependencies_type::iterator dep_it)
+ {
+ const boost::shared_ptr<typename nonvoid_future_body_base<T>::type> body = *dep_it;
+
+ boost::shared_ptr<dependency_eraser_info> eraser_info(new dependency_eraser_info);
+ eraser_info->iterator = dep_it;
+ eraser_info->iterator_valid = true;
+ eraser_info->waiter_connection = _waiter_callbacks.observe(body->waiter_callbacks());
+
+ typedef typename future_body_untyped_base::update_signal_type::slot_type update_slot_type;
+ update_slot_type update_slot(&future_selector_body::check_dependency, this,
+ make_weak(body), eraser_info);
+ update_slot.track(this->shared_from_this());
+ boost::signals2::connection conn;
+ conn = body->connectUpdate(update_slot);
+ // deal with futures which completed before we got them
+ try
+ {
+ update_slot();
+ }
+ catch(const boost::signals2::expired_slot &)
+ {
+ conn.disconnect();
+ }
+ }
+
+ waiter_event_queue _waiter_callbacks;
+ mutable boost::mutex _mutex;
+ mutable boost::condition _condition;
+ selected_container_type _selected_promises;
+ fulfilled_container_type _fulfilled_promises;
+ boost::shared_ptr<dependent_type> _selected;
+ dependencies_type _dependencies;
+ std::size_t _dependencies_size;
+ };
+
+ /* future_body for void futures returned by future_select. Becomes ready
+ when any of the futures on its list have become ready or has an exception.
+ */
+ template<typename T>
+ class future_select_body;
+
+ template<>
+ class future_select_body<void>:
+ public virtual future_body_untyped_base
+ {
+ typedef boost::shared_ptr<future_body_untyped_base > future_body_dependency_type;
+ // needed by msvc9
+ template<typename U>
+ friend class future_select_body;
+ public:
+ typedef future_body_untyped_base::update_signal_type update_signal_type;
+
+ template<typename InputIterator>
+ static boost::shared_ptr<future_select_body> create(InputIterator future_begin, InputIterator future_end)
+ {
+ boost::shared_ptr<future_select_body> new_object(new future_select_body);
+ init(new_object, future_begin, future_end);
+ return new_object;
+ }
+
+ virtual bool ready() const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ return nolock_ready();
+ }
+ virtual void join() const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ condition().wait(lock, boost::bind(&future_select_body::check_if_complete, this, &lock));
+ }
+ virtual bool timed_join(const boost::system_time &absolute_time) const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ return condition().timed_wait(lock, absolute_time, boost::bind(&future_select_body::check_if_complete, this, &lock));
+ }
+ virtual void cancel(const poet::exception_ptr &exp)
+ {}
+ virtual exception_ptr get_exception_ptr() const
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ if(!_first_complete_dependency) return exception_ptr();
+ return _first_complete_dependency->get_exception_ptr();
+ }
+ virtual waiter_event_queue& waiter_callbacks() const
+ {
+ return _waiter_callbacks;
+ }
+ protected:
+ future_select_body(): _waiter_callbacks(future_body_untyped_base::mutex(), future_body_untyped_base::condition())
+ {}
+ template<typename InputIterator>
+ static void init(const boost::shared_ptr<future_select_body> &new_object, InputIterator future_begin, InputIterator future_end)
+ {
+ new_object->_waiter_callbacks.set_owner(new_object);
+
+ InputIterator it;
+ for(it = future_begin; it != future_end; ++it)
+ {
+ typedef update_signal_type::slot_type update_slot_type;
+ update_slot_type update_slot(&future_select_body::check_dependency, new_object.get(),
+ make_weak(get_future_body(*it)));
+ update_slot.track(new_object);
+ boost::signals2::connection conn;
+ conn = get_future_body(*it)->connectUpdate(update_slot);
+ try
+ {
+ update_slot();
+ }
+ catch(const boost::signals2::expired_slot &)
+ {
+ conn.disconnect();
+ break;
+ }
+
+ new_object->waiter_callbacks().observe(get_future_body(*it)->waiter_callbacks());
+
+ new_object->_dependencies.push_back(get_future_body(*it));
+ }
+ }
+ bool check_if_complete(boost::unique_lock<boost::mutex> *lock) const
+ {
+ if(_first_complete_dependency) return true;
+ lock->unlock();
+ _waiter_callbacks.poll();
+ lock->lock();
+ return _first_complete_dependency;
+ }
+
+ mutable future_body_dependency_type _first_complete_dependency;
+ private:
+ void check_dependency(const boost::weak_ptr<future_body_untyped_base> &weak_dependency) const
+ {
+ boost::shared_ptr<future_body_untyped_base> dependency(weak_dependency);
+ if(dependency == false)
+ {
+ throw boost::signals2::expired_slot();
+ }
+ bool emit_signal = false;
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ if(!_first_complete_dependency)
+ {
+ if(dependency->ready() || dependency->get_exception_ptr())
+ {
+ _first_complete_dependency = dependency;
+ _dependencies.clear();
+ emit_signal = true;
+ condition().notify_all();
+ }
+ }
+ }
+ if(emit_signal)
+ {
+ this->_updateSignal();
+ _waiter_callbacks.close_posting();
+ throw boost::signals2::expired_slot();
+ }
+ }
+ bool nolock_ready() const
+ {
+ if(!_first_complete_dependency) return false;
+ return _first_complete_dependency->ready();
+ }
+
+ mutable std::vector<boost::shared_ptr<future_body_untyped_base> > _dependencies;
+ mutable waiter_event_queue _waiter_callbacks;
+ };
+
+ template<typename T>
+ class future_select_body: public future_select_body<void>,
+ public future_body_base<T>
+ {
+ typedef boost::shared_ptr<future_body_base<T> > future_body_dependency_type;
+ public:
+ typedef future_body_untyped_base::update_signal_type update_signal_type;
+
+ template<typename InputIterator>
+ static boost::shared_ptr<future_select_body> create(InputIterator future_begin, InputIterator future_end)
+ {
+ boost::shared_ptr<future_select_body> new_object(new future_select_body);
+ new_object->init(new_object, future_begin, future_end);
+ return new_object;
+ }
+
+ virtual const T& getValue() const
+ {
+ boost::shared_ptr<future_body_base<T> > typed_dependency;
+ {
+ boost::unique_lock<boost::mutex> lock(mutex());
+ condition().wait(lock, boost::bind(&future_select_body<void>::check_if_complete, this, &lock));
+ typed_dependency =
+ boost::dynamic_pointer_cast<future_body_base<T> >(_first_complete_dependency);
+ }
+ return typed_dependency->getValue();
+ }
+ virtual void setValue(const T &value)
+ {
+ BOOST_ASSERT(false);
+ }
+ private:
+ future_select_body()
+ {}
+#ifdef BOOST_MSVC
+#pragma warning( suppress : 4250 ) // suppress msvc 9 warning
+#endif
+ };
+ } // namespace detail
+
+ template<typename T>
+ class future_selector
+ {
+ public:
+ typedef future<T> value_type;
+ typedef std::size_t size_type;
+ typedef std::ptrdiff_t difference_type;
+
+ future_selector(): _selector_body(detail::future_selector_body<T>::create())
+ {}
+ future_selector(const future_selector &other):
+ _selector_body(other._selector_body->clone())
+ {}
+
+ ~future_selector()
+ {
+ _selector_body->detach();
+ }
+
+ future_selector& operator=(const future_selector &rhs)
+ {
+ if(&rhs == this) return *this;
+ future_selector temp(rhs);
+ swap(temp);
+ return *this;
+ }
+ future<T> selected() const
+ {
+ return _selector_body->selected();
+ }
+ void pop_selected()
+ {
+ _selector_body->pop_selected();
+ }
+ void push(const future<T> &f)
+ {
+ _selector_body->push(f);
+ }
+ template<typename Converter, typename ExceptionHandler, typename U>
+ void push(const Converter &converter, const ExceptionHandler &exception_handler, const future<U> &f)
+ {
+ future<T> converted_f = future_combining_barrier<T>(converter, exception_handler, f);
+ push(converted_f);
+ }
+ difference_type size() const
+ {
+ return _selector_body->size();
+ }
+ void reset()
+ {
+ future_selector temp;
+ swap(temp);
+ }
+ void swap(future_selector &other)
+ {
+ using std::swap;
+ swap(_selector_body, other._selector_body);
+ }
+ private:
+ boost::shared_ptr<detail::future_selector_body<T> > _selector_body;
+ };
+
+ template<typename T>
+ void swap(future_selector<T> &a, future_selector<T> &b)
+ {
+ a.swap(b);
+ }
+
+ template<typename InputIterator>
+ typename std::iterator_traits<InputIterator>::value_type future_select_range(InputIterator future_begin, InputIterator future_end)
+ {
+ typedef typename std::iterator_traits<InputIterator>::value_type future_type;
+ if(future_begin == future_end) return future_type();
+ typedef detail::future_select_body<typename future_type::value_type> body_type;
+ future_type result = detail::create_future<typename future_type::value_type>(
+ body_type::create(future_begin, future_end));
+ return result;
+ }
+}
+
+#ifndef POET_FUTURE_SELECT_MAX_ARGS
+#define POET_FUTURE_SELECT_MAX_ARGS 10
+#endif
+
+#define BOOST_PP_ITERATION_LIMITS (2, POET_FUTURE_SELECT_MAX_ARGS)
+#define BOOST_PP_FILENAME_1 <poet/detail/future_select_template.hpp>
+#include BOOST_PP_ITERATE()
+
+#endif // _POET_FUTURE_WAITS_HPP
Added: sandbox/libpoet/trunk/poet/monitor.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/monitor.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,209 @@
+/*
+ An experimental alternative to monitor_ptr that stores the wrapped
+ object by value instead of acting like a pointer.
+
+ begin: Frank Mori Hess <fmhess_at_[hidden]> 2007-11-29
+ copyright (c) Frank Mori Hess 2007-2008
+*/
+
+// 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 _POET_MONITOR_HPP
+#define _POET_MONITOR_HPP
+
+#include <algorithm>
+#include <boost/optional.hpp>
+#include <boost/preprocessor/repetition.hpp>
+#include <boost/scoped_ptr.hpp>
+#include <poet/detail/preprocessor_macros.hpp>
+#include <poet/detail/utility.hpp>
+#include <poet/monitor_locks.hpp>
+#include <poet/monitor_ptr.hpp>
+
+#ifndef POET_MONITOR_MAX_CONSTRUCTOR_ARGS
+#define POET_MONITOR_MAX_CONSTRUCTOR_ARGS 10
+#endif
+
+namespace poet
+{
+ template<typename T, typename Mutex = boost::mutex>
+ class monitor
+ {
+ public:
+ typedef T element_type;
+ typedef T value_type;
+ typedef Mutex mutex_type;
+
+ class scoped_lock: public monitor_ptr<T, Mutex>::scoped_lock
+ {
+ typedef typename monitor_ptr<T, Mutex>::scoped_lock base_class;
+ public:
+ scoped_lock(monitor<T, Mutex> &mon):
+ base_class(mon._monitor_pointer)
+ {}
+ explicit scoped_lock(const monitor<T, Mutex> &mon):
+ base_class(mon._monitor_pointer)
+ {}
+ scoped_lock(monitor<T, Mutex> &mon, bool do_lock):
+ base_class(mon._monitor_pointer, do_lock)
+ {}
+ explicit scoped_lock(const monitor<T, Mutex> &mon, bool do_lock):
+ base_class(mon._monitor_pointer, do_lock)
+ {}
+ };
+
+ class scoped_try_lock: public monitor_ptr<T, Mutex>::scoped_try_lock
+ {
+ typedef typename monitor_ptr<T, Mutex>::scoped_try_lock base_class;
+ public:
+ scoped_try_lock(monitor<T, Mutex> &mon): base_class(mon._monitor_pointer)
+ {}
+ explicit scoped_try_lock(const monitor<T, Mutex> &mon): base_class(mon._monitor_pointer)
+ {}
+ scoped_try_lock(monitor<T, Mutex> &mon, bool do_lock):
+ base_class(mon._monitor_pointer, do_lock)
+ {}
+ explicit scoped_try_lock(const monitor<T, Mutex> &mon, bool do_lock):
+ base_class(mon._monitor_pointer, do_lock)
+ {}
+ };
+
+ class scoped_timed_lock: public monitor_ptr<T, Mutex>::scoped_timed_lock
+ {
+ typedef typename monitor_ptr<T, Mutex>::scoped_timed_lock base_class;
+ public:
+ template<typename Timeout>
+ scoped_timed_lock(monitor<T, Mutex> &mon, const Timeout &t):
+ base_class(mon._monitor_pointer, t)
+ {}
+ template<typename Timeout>
+ explicit scoped_timed_lock(const monitor<T, Mutex> &mon, const Timeout &t):
+ base_class(mon._monitor_pointer, t)
+ {}
+ scoped_timed_lock(monitor<T, Mutex> &mon, bool do_lock):
+ base_class(mon._monitor_pointer, do_lock)
+ {}
+ explicit scoped_timed_lock(const monitor<T, Mutex> &mon, bool do_lock):
+ base_class(mon._monitor_pointer, do_lock)
+ {}
+ };
+
+ monitor(): _monitor_pointer(new T)
+ {}
+ monitor(const T &object): _monitor_pointer(new T(object))
+ {}
+ monitor(const monitor &other)
+ {
+ scoped_lock lock(other);
+ _monitor_pointer.reset(new T((*lock)));
+ }
+ template<typename U, typename M>
+ monitor(const monitor<U, M> &other)
+ {
+ typename monitor<U, M>::scoped_lock lock(other);
+ _monitor_pointer.reset(new T((*lock)));
+ }
+#define POET_BASE_MONITOR_TEMPLATE_CONSTRUCTOR(z, n, dummy) \
+ template<POET_REPEATED_TYPENAMES(n, U)> \
+ monitor(POET_REPEATED_ARG_DECLARATIONS(n, U)): _monitor_pointer(new T(POET_REPEATED_ARG_NAMES(n, arg))) \
+ {}
+ BOOST_PP_REPEAT_FROM_TO(1, BOOST_PP_INC(POET_MONITOR_MAX_CONSTRUCTOR_ARGS), POET_BASE_MONITOR_TEMPLATE_CONSTRUCTOR, x)
+#undef POET_BASE_MONITOR_TEMPLATE_CONSTRUCTOR
+ virtual ~monitor() {}
+
+ monitor& operator=(const monitor &rhs)
+ {
+ return operator=<T, Mutex>(rhs);
+ }
+ template<typename U, typename M>
+ monitor& operator=(const monitor<U, M> &rhs)
+ {
+ if(&rhs == this) return *this;
+ monitor_unique_lock<const monitor_ptr<U, M> > other_lock(rhs._monitor_pointer, boost::defer_lock_t());
+ monitor_unique_lock<monitor_ptr<T, Mutex> > this_lock(_monitor_pointer, boost::defer_lock_t());
+ detail::lock_pair(this_lock, other_lock);
+ *this_lock = *other_lock;
+ return *this;
+ }
+
+ template<typename M>
+ void swap(monitor<T, M> &other)
+ {
+ monitor_unique_lock<monitor_ptr<T, M> > other_lock(other._monitor_pointer, boost::defer_lock_t());
+ monitor_unique_lock<monitor_ptr<T, Mutex> > this_lock(_monitor_pointer, boost::defer_lock_t());
+ detail::lock_pair(this_lock, other_lock);
+ using std::swap;
+ swap(*this_lock, *other_lock);
+ }
+
+ monitor_unique_lock<monitor> operator->()
+ {
+ return monitor_unique_lock<monitor>(*this);
+ }
+ monitor_unique_lock<const monitor> operator->() const
+ {
+ return monitor_unique_lock<const monitor>(*this);
+ }
+
+ const monitor_ptr<T, Mutex> & get_monitor_ptr()
+ {
+ return _monitor_pointer;
+ }
+ monitor_ptr<const T, Mutex> get_monitor_ptr() const
+ {
+ return _monitor_pointer;
+ }
+// Boost.Threads interface for Lockable concepts
+// Lockable
+ void lock() const {_monitor_pointer.lock();}
+ bool try_lock() const {return _monitor_pointer.try_lock();}
+ void unlock() const {_monitor_pointer.unlock();}
+// TimedLockable
+ template<typename Timeout>
+ bool timed_lock(const Timeout &timeout) const {return _monitor_pointer.timed_lock(timeout);}
+// SharedLockable
+ void lock_shared() const {_monitor_pointer.lock_shared();}
+ bool try_lock_shared() const {return _monitor_pointer.try_lock_shared();}
+ template<typename Timeout>
+ bool timed_lock_shared(const Timeout &timeout) const
+ {
+ return _monitor_pointer.timed_lock_shared(timeout);
+ }
+ void unlock_shared() const {_monitor_pointer.unlock_shared();}
+ void unlock_and_lock_shared() const {_monitor_pointer.unlock_and_lock_shared();}
+// UpgradeLockable
+ void lock_upgrade() const {_monitor_pointer.lock_upgrade();}
+ void unlock_upgrade() const {_monitor_pointer.unlock_upgrade();}
+ void unlock_upgrade_and_lock() const {_monitor_pointer.unlock_upgrade_and_lock();}
+ void unlock_upgrade_and_lock_shared() const {_monitor_pointer.unlock_upgrade_and_lock_shared();}
+ void unlock_and_lock_upgrade() const {_monitor_pointer.unlock_and_lock_upgrade();}
+ protected:
+ template<typename U, typename M>
+ friend class monitor;
+
+ monitor_ptr<T, Mutex> _monitor_pointer;
+ };
+
+ template<typename T, typename Mutex>
+ void swap(poet::monitor<T, Mutex> &mon0, poet::monitor<T, Mutex> &mon1)
+ {
+ mon0.swap(mon1);
+ }
+
+ template<typename T, typename Mutex>
+ const monitor_ptr<T, Mutex> & get_monitor_ptr(monitor<T, Mutex> &mon)
+ {
+ return mon.get_monitor_ptr();
+ }
+ template<typename T, typename Mutex>
+ monitor_ptr<const T, Mutex> get_monitor_ptr(const monitor<T, Mutex> &mon)
+ {
+ return mon.get_monitor_ptr();
+ }
+};
+
+#undef POET_SPECIALIZED_MONITOR_TEMPLATE_CONSTRUCTOR
+
+#endif // _POET_MONITOR_HPP
Added: sandbox/libpoet/trunk/poet/monitor_base.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/monitor_base.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,60 @@
+/*
+ By deriving from monitor_base, an object can release the
+ mutex of the monitor_ptr which owns it and wait to be
+ notified.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-08-27
+*/
+
+// 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 _POET_MONITOR_BASE_HPP
+#define _POET_MONITOR_BASE_HPP
+
+#include <boost/function.hpp>
+#include <poet/detail/monitor_synchronizer.hpp>
+#include <poet/mutex_properties.hpp>
+
+namespace poet
+{
+ template<typename T, typename Mutex>
+ class monitor_ptr;
+ namespace detail
+ {
+ class monitor_synchronizer_base;
+ };
+
+ class monitor_base
+ {
+ public:
+ /* Does nothing except prevent _syncer from being disturbed
+ on assignment by default assignment operator. It's fine if derived
+ class overrides this and doesn't call it, since it doesn't do anything! */
+ monitor_base& operator=(const monitor_base &rhs)
+ {
+ return *this;
+ }
+ protected:
+ inline void wait() const;
+ template<typename Pred>
+ void wait(Pred pred) const
+ {
+ _syncer->wait(pred);
+ };
+ inline void notify_one() const;
+ inline void notify_all() const;
+ private:
+ template<typename T, typename Mutex>
+ friend class monitor_ptr;
+
+ inline void set_synchronizer(const boost::shared_ptr<detail::monitor_synchronizer_base> &syncer) const;
+
+ mutable boost::shared_ptr<detail::monitor_synchronizer_base> _syncer;
+ };
+};
+
+#include <poet/detail/monitor_base.ipp>
+
+#endif // _POET_MONITOR_BASE_DECL_HPP
Added: sandbox/libpoet/trunk/poet/monitor_locks.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/monitor_locks.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,536 @@
+/*
+ Extensions of Boost.Thread lock classes, which add support for
+ operator->() and operator*(). Used in conjunction with
+ monitor_ptr and monitor classes.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-08-27
+*/
+
+// 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 _POET_MONITOR_LOCKS_HPP
+#define _POET_MONITOR_LOCKS_HPP
+
+#include <boost/bind.hpp>
+#include <boost/config.hpp>
+#include <boost/function.hpp>
+#include <boost/thread/condition.hpp>
+#include <boost/thread/exceptions.hpp>
+#include <boost/thread/locks.hpp>
+#include <poet/detail/monitor_synchronizer.hpp>
+#include <poet/monitor_ptr.hpp>
+
+namespace poet
+{
+ template<typename T, typename Mutex>
+ class monitor_ptr;
+ template<typename T, typename Mutex>
+ class monitor;
+ template<typename Monitor>
+ class monitor_upgrade_lock;
+ template<typename UpgradeLock>
+ class monitor_upgrade_to_unique_lock;
+ template<typename T, typename U, typename Mutex>
+ inline monitor_ptr<T, Mutex> const_pointer_cast(const monitor_ptr<U, Mutex> &pointer);
+
+ namespace detail
+ {
+ // figure out const-correct monitor_ptr type to use as handle
+ // default
+ template<typename Monitor>
+ class monitor_handle
+ {
+ public:
+ typedef monitor_ptr<typename Monitor::element_type, typename Monitor::mutex_type> type;
+ };
+ // partial specialization for poet::monitor, whose constness is transitive
+ template<typename T, typename Mutex>
+ class monitor_handle<const monitor<T, Mutex> >
+ {
+ public:
+ typedef monitor_ptr<const T, Mutex> type;
+ };
+
+ template<typename Monitor, typename MonitorHandle, typename Lock>
+ class lock_wrapper
+ {
+ typedef MonitorHandle monitor_ptr_type;
+ public:
+ typedef Monitor monitor_type;
+ typedef typename monitor_ptr_type::element_type element_type;
+
+ lock_wrapper(): _mon_raw_ptr(0)
+ {}
+ explicit lock_wrapper(Monitor &mon):
+ _mon(get_monitor_ptr(mon)), _mon_raw_ptr(&mon),
+ _lock(_mon.get_syncer()->_mutex)
+ {
+ set_wait_function();
+ }
+ template<typename U>
+ lock_wrapper(Monitor &mon, const U &arg):
+ _mon(get_monitor_ptr(mon)), _mon_raw_ptr(&mon),
+ _lock(_mon.get_syncer()->_mutex, arg)
+ {
+ set_wait_function();
+ }
+ template<typename OtherLock>
+ lock_wrapper(boost::detail::thread_move_t<OtherLock> other):
+ _mon(other->_mon), _mon_raw_ptr(other->_mon_raw_ptr), _lock(other->_lock.move())
+ {
+ set_wait_function();
+ }
+
+ // unique/shared_lock interface
+ void swap(lock_wrapper &other)
+ {
+ using std::swap;
+ swap(_mon, other._mon);
+ swap(_mon_raw_ptr, other._mon_raw_ptr);
+ _lock.swap(other._lock);
+ set_wait_function();
+ other.set_wait_function();
+ }
+ void lock()
+ {
+ _lock.lock();
+ set_wait_function();
+ }
+ bool try_lock()
+ {
+ bool successful = _lock.try_lock();
+ set_wait_function();
+ return successful;
+ }
+ template<typename Timeout>
+ bool timed_lock(const Timeout &timeout)
+ {
+ bool successful = _lock.timed_lock(timeout);
+ set_wait_function();
+ return successful;
+ }
+ void unlock()
+ {
+ _lock.unlock();
+ }
+ bool owns_lock() const
+ {
+ return _lock.owns_lock();
+ }
+ bool locked() const // backwards compatibility
+ {
+ return owns_lock();
+ }
+ // safe bool idiom, somewhat safer than providing conversion to bool operator
+ typedef Lock * Lock::* unspecified_bool_type;
+ operator unspecified_bool_type() const
+ {
+ return !_lock ? 0 : &_lock;
+ }
+ bool operator!() const
+ {
+ return !_lock;
+ }
+ Monitor* mutex() const
+ {
+ return _mon_raw_ptr;
+ }
+ Monitor* release()
+ {
+ Monitor * result = _mon_raw_ptr;
+ _mon_raw_ptr = 0;
+ _mon.reset();
+ _lock.release();
+ return result;
+ }
+
+ // monitor extensions to lock interface
+ element_type* operator->() const
+ {
+ if(owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return _mon.direct().get();
+ }
+ element_type& operator*() const
+ {
+ if(owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return *_mon.direct().get();
+ }
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+ protected:
+#endif // BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+ monitor_ptr_type _mon;
+#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+ private:
+ template<typename Lockable>
+ friend class monitor_shared_lock;
+ template<typename Lockable>
+ friend class monitor_upgrade_lock;
+ template<typename UpgradeLock>
+ friend class monitor_upgrade_to_unique_lock;
+ template<typename M, typename MH, typename L>
+ friend class lock_wrapper;
+#endif // BOOST_NO_MEMBER_TEMPLATE_FRIENDS
+
+ void set_wait_function()
+ {
+ if(_lock.owns_lock())
+ {
+ typename detail::monitor_synchronizer<typename Monitor::mutex_type>::wait_function_type wait_func = boost::bind(
+ &lock_wrapper::wait_function, this, _1, _2);
+ _mon.get_syncer()->set_wait_function(wait_func);
+ }
+ }
+ void wait_function(boost::condition &condition, const boost::function<bool ()> &pred)
+ {
+ if(pred == 0)
+ condition.wait(_lock);
+ else
+ condition.wait(_lock, pred);
+ }
+ // non-copyable
+ lock_wrapper(lock_wrapper &);
+ lock_wrapper& operator=(lock_wrapper&);
+
+ Monitor *_mon_raw_ptr;
+ Lock _lock;
+ };
+ }
+
+ template<typename Monitor>
+ class monitor_unique_lock: public detail::lock_wrapper<Monitor,
+ typename detail::monitor_handle<Monitor>::type,
+ boost::unique_lock<typename Monitor::mutex_type> >
+ {
+ typedef detail::lock_wrapper<Monitor,
+ typename detail::monitor_handle<Monitor>::type,
+ boost::unique_lock<typename Monitor::mutex_type> >
+ base_class;
+ public:
+ monitor_unique_lock()
+ {}
+ explicit monitor_unique_lock(Monitor &mon): base_class(mon)
+ {}
+ template<typename U>
+ monitor_unique_lock(Monitor &mon, const U &arg):
+ base_class(mon, arg)
+ {}
+ // move constructors
+ monitor_unique_lock(boost::detail::thread_move_t<monitor_unique_lock> other):
+ base_class(other)
+ {}
+ monitor_unique_lock(boost::detail::thread_move_t<monitor_upgrade_lock<Monitor> > other):
+ base_class(other)
+ {}
+
+ // move emulation
+ boost::detail::thread_move_t<monitor_unique_lock> move()
+ {
+ return boost::detail::thread_move_t<monitor_unique_lock>(*this);
+ }
+ template<typename Lock>
+ monitor_unique_lock& operator=(boost::detail::thread_move_t<Lock> other)
+ {
+ monitor_unique_lock temp(other);
+ this->swap(temp);
+ return *this;
+ }
+ operator boost::detail::thread_move_t<monitor_unique_lock>()
+ {
+ return move();
+ }
+ };
+
+ template<typename Monitor>
+ void swap(monitor_unique_lock<Monitor> &lockA, monitor_unique_lock<Monitor> &lockB)
+ {
+ lockA.swap(lockB);
+ }
+
+ template<typename Monitor>
+ boost::detail::thread_move_t<monitor_unique_lock<Monitor> >
+ move(monitor_unique_lock<Monitor> &lock)
+ {
+ return lock.move();
+ }
+
+ template<typename Monitor>
+ class monitor_shared_lock: public detail::lock_wrapper<Monitor,
+ monitor_ptr<typename Monitor::element_type, typename Monitor::mutex_type>,
+ boost::shared_lock<typename Monitor::mutex_type > >
+ {
+ typedef detail::lock_wrapper<Monitor,
+ monitor_ptr<typename Monitor::element_type, typename Monitor::mutex_type>,
+ boost::shared_lock<typename Monitor::mutex_type> >
+ base_class;
+ public:
+ monitor_shared_lock()
+ {}
+ explicit monitor_shared_lock(Monitor &mon): base_class(mon)
+ {}
+ template<typename U>
+ monitor_shared_lock(Monitor &mon, const U &arg):
+ base_class(mon, arg)
+ {}
+ // move constructors
+ monitor_shared_lock(boost::detail::thread_move_t<monitor_shared_lock> other):
+ base_class(other)
+ {}
+ monitor_shared_lock(boost::detail::thread_move_t<monitor_upgrade_lock<Monitor> > other):
+ base_class(other)
+ {}
+ monitor_shared_lock(boost::detail::thread_move_t<monitor_unique_lock<Monitor> > other):
+ base_class(other)
+ {}
+
+ // monitor extensions to lock interface, only allow pointer to const access for shared_lock
+ const typename base_class::element_type* operator->() const
+ {
+ if(this->owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return this->_mon.direct().get();
+ }
+ const typename base_class::element_type& operator*() const
+ {
+ if(this->owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return *this->_mon.direct().get();
+ }
+
+ // move emulation
+ boost::detail::thread_move_t<monitor_shared_lock> move()
+ {
+ return boost::detail::thread_move_t<monitor_shared_lock>(*this);
+ }
+ template<typename Lock>
+ monitor_shared_lock& operator=(boost::detail::thread_move_t<Lock> other)
+ {
+ monitor_shared_lock temp(other);
+ this->swap(temp);
+ return *this;
+ }
+ operator boost::detail::thread_move_t<monitor_shared_lock>()
+ {
+ return move();
+ }
+ };
+
+ template<typename Monitor>
+ void swap(monitor_shared_lock<Monitor> &lockA, monitor_shared_lock<Monitor> &lockB)
+ {
+ lockA.swap(lockB);
+ }
+
+ template<typename Monitor>
+ boost::detail::thread_move_t<monitor_shared_lock<Monitor> >
+ move(monitor_shared_lock<Monitor> &lock)
+ {
+ return lock.move();
+ }
+
+ template<typename Monitor>
+ class monitor_upgrade_lock: public detail::lock_wrapper<Monitor,
+ monitor_ptr<typename Monitor::element_type, typename Monitor::mutex_type>,
+ boost::upgrade_lock<typename Monitor::mutex_type> >
+ {
+ typedef detail::lock_wrapper<Monitor,
+ monitor_ptr<typename Monitor::element_type, typename Monitor::mutex_type>,
+ boost::upgrade_lock<typename Monitor::mutex_type> >
+ base_class;
+ public:
+ monitor_upgrade_lock()
+ {}
+ explicit monitor_upgrade_lock(Monitor &mon): base_class(mon)
+ {}
+ template<typename U>
+ monitor_upgrade_lock(Monitor &mon, const U &arg):
+ base_class(mon, arg)
+ {}
+ // move constructors
+ monitor_upgrade_lock(boost::detail::thread_move_t<monitor_upgrade_lock> other):
+ base_class(other)
+ {}
+ monitor_upgrade_lock(boost::detail::thread_move_t<monitor_unique_lock<Monitor> > other):
+ base_class(other)
+ {}
+
+ // monitor extensions to lock interface, only allow pointer to const access for upgrade_lock
+ const typename base_class::element_type* operator->() const
+ {
+ if(this->owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return this->_mon.direct().get();
+ }
+ const typename base_class::element_type& operator*() const
+ {
+ if(this->owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return *this->_mon.direct().get();
+ }
+
+ // move emulation
+ boost::detail::thread_move_t<monitor_upgrade_lock> move()
+ {
+ return boost::detail::thread_move_t<monitor_upgrade_lock>(*this);
+ }
+ template<typename Lock>
+ monitor_upgrade_lock& operator=(boost::detail::thread_move_t<Lock> other)
+ {
+ monitor_upgrade_lock temp(other);
+ this->swap(temp);
+ return *this;
+ }
+ operator boost::detail::thread_move_t<monitor_upgrade_lock>()
+ {
+ return move();
+ }
+ };
+
+ template<typename Monitor>
+ void swap(monitor_upgrade_lock<Monitor> &lockA, monitor_upgrade_lock<Monitor> &lockB)
+ {
+ lockA.swap(lockB);
+ }
+
+ template<typename Monitor>
+ boost::detail::thread_move_t<monitor_upgrade_lock<Monitor> >
+ move(monitor_upgrade_lock<Monitor> &lock)
+ {
+ return lock.move();
+ }
+
+ template<typename Monitor>
+ class monitor_upgrade_to_unique_lock
+ {
+ typedef boost::upgrade_to_unique_lock<typename Monitor::mutex_type> wrapped_lock_type;
+ typedef typename detail::monitor_handle<Monitor>::type monitor_ptr_type;
+ public:
+ typedef Monitor monitor_type;
+ typedef typename monitor_ptr_type::element_type element_type;
+
+ explicit monitor_upgrade_to_unique_lock(monitor_upgrade_lock<Monitor> &upgrade_lock):
+ _mon(upgrade_lock._mon),
+ _lock(upgrade_lock._lock)
+ {}
+ // move constructor
+ monitor_upgrade_to_unique_lock(boost::detail::thread_move_t<monitor_upgrade_to_unique_lock> other):
+ _mon(other->_mon), _lock(boost::detail::thread_move_t<wrapped_lock_type>(other->_lock))
+ {}
+
+ void swap(monitor_upgrade_to_unique_lock &other)
+ {
+ using std::swap;
+ swap(_mon, other._mon);
+ _lock.swap(other._lock);
+ }
+ bool operator!()
+ {
+ return !_lock;
+ }
+ // safe bool idiom, somewhat safer than providing conversion to bool operator
+ typedef wrapped_lock_type * wrapped_lock_type::* unspecified_bool_type;
+ operator unspecified_bool_type() const
+ {
+ return !_lock ? 0 : &_lock;
+ }
+ bool owns_lock() const
+ {
+ return _lock.owns_lock();
+ }
+
+ // monitor extensions to lock interface
+ element_type* operator->() const
+ {
+ if(this->owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return _mon.direct().get();
+ }
+ element_type& operator*() const
+ {
+ if(this->owns_lock() == false)
+ {
+ throw boost::lock_error();
+ }
+ return *_mon.direct().get();
+ }
+
+ // move emulation
+ boost::detail::thread_move_t<monitor_upgrade_to_unique_lock> move()
+ {
+ return boost::detail::thread_move_t<monitor_upgrade_to_unique_lock>(*this);
+ }
+ monitor_upgrade_to_unique_lock& operator=(boost::detail::thread_move_t<monitor_upgrade_to_unique_lock> other)
+ {
+ monitor_upgrade_to_unique_lock temp(other);
+ swap(temp);
+ return *this;
+ }
+ operator boost::detail::thread_move_t<monitor_upgrade_to_unique_lock>()
+ {
+ return move();
+ }
+ private:
+ monitor_ptr_type _mon;
+ wrapped_lock_type _lock;
+ };
+
+ template<typename Monitor>
+ void swap(monitor_upgrade_to_unique_lock<Monitor> &lockA, monitor_upgrade_to_unique_lock<Monitor> &lockB)
+ {
+ lockA.swap(lockB);
+ }
+
+ template<typename Monitor>
+ boost::detail::thread_move_t<monitor_upgrade_to_unique_lock<Monitor> >
+ move(monitor_upgrade_to_unique_lock<Monitor> &lock)
+ {
+ return lock.move();
+ }
+};
+
+namespace boost
+{
+ template<typename T>
+ detail::thread_move_t<poet::monitor_unique_lock<T> >
+ move(const detail::thread_move_t<poet::monitor_unique_lock<T> > &x)
+ {
+ return x;
+ }
+ template<typename T>
+ detail::thread_move_t<poet::monitor_shared_lock<T> >
+ move(const detail::thread_move_t<poet::monitor_shared_lock<T> > &x)
+ {
+ return x;
+ }
+ template<typename T>
+ detail::thread_move_t<poet::monitor_upgrade_lock<T> >
+ move(const detail::thread_move_t<poet::monitor_upgrade_lock<T> > &x)
+ {
+ return x;
+ }
+ template<typename T>
+ detail::thread_move_t<poet::monitor_upgrade_to_unique_lock<T> >
+ move(const detail::thread_move_t<poet::monitor_upgrade_to_unique_lock<T> > &x)
+ {
+ return x;
+ }
+}
+
+#endif // _POET_MONITOR_LOCKS_HPP
Added: sandbox/libpoet/trunk/poet/monitor_ptr.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/monitor_ptr.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,316 @@
+/*
+ A wrapper which automatically locks/unlocks a mutex whenever the wrapped
+ objects members are accessed. See "Wrapping C++ Member Function Calls"
+ by Bjarne Stroustroup at http://www.research.att.com/~bs/wrapper.pdf
+
+ begin: Frank Mori Hess <fmhess_at_[hidden]> 2007-08-27
+ copyright (c) Frank Mori Hess 2007-2008
+*/
+
+// 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 _POET_MONITOR_PTR_HPP
+#define _POET_MONITOR_PTR_HPP
+
+#include <boost/shared_ptr.hpp>
+#include <boost/thread/mutex.hpp>
+#include <poet/monitor_locks.hpp>
+#include <poet/detail/monitor_synchronizer.hpp>
+#include <poet/monitor_base.hpp>
+#include <poet/monitor_locks.hpp>
+
+namespace poet
+{
+ template<typename Monitor>
+ class monitor_unique_lock;
+ namespace detail
+ {
+ template<typename Monitor, typename MonitorHandle, typename Lock>
+ class lock_wrapper;
+ }
+
+ // uses default copy constructor/assignment operators
+ template<typename T, typename Mutex = boost::mutex>
+ class monitor_ptr
+ {
+ public:
+ typedef T element_type;
+ typedef Mutex mutex_type;
+
+ class scoped_lock: public monitor_unique_lock<const monitor_ptr>
+ {
+ typedef monitor_unique_lock<const monitor_ptr> base_class;
+ public:
+ scoped_lock(monitor_ptr &monitor_pointer):
+ base_class(monitor_pointer)
+ {}
+ explicit scoped_lock(const monitor_ptr<T, Mutex> &monitor_pointer):
+ base_class(monitor_pointer)
+ {}
+ scoped_lock(monitor_ptr &monitor_pointer, bool do_lock):
+ base_class(monitor_pointer, boost::defer_lock_t())
+ {
+ if(do_lock) base_class::lock();
+ }
+ explicit scoped_lock(const monitor_ptr &monitor_pointer, bool do_lock):
+ base_class(monitor_pointer, boost::defer_lock_t())
+ {
+ if(do_lock) base_class::lock();
+ }
+ };
+
+ class scoped_try_lock: public monitor_unique_lock<const monitor_ptr>
+ {
+ typedef monitor_unique_lock<const monitor_ptr> base_class;
+ public:
+ scoped_try_lock(monitor_ptr &monitor_pointer):
+ base_class(monitor_pointer, boost::try_to_lock_t())
+ {}
+ explicit scoped_try_lock(const monitor_ptr &monitor_pointer):
+ base_class(monitor_pointer, boost::try_to_lock_t())
+ {}
+ scoped_try_lock(monitor_ptr &monitor_pointer, bool do_lock):
+ base_class(monitor_pointer, boost::defer_lock_t())
+ {
+ if(do_lock) base_class::lock();
+ }
+ explicit scoped_try_lock(const monitor_ptr &monitor_pointer, bool do_lock):
+ base_class(monitor_pointer, boost::defer_lock_t())
+ {
+ if(do_lock) base_class::lock();
+ }
+ };
+
+ class scoped_timed_lock: public monitor_unique_lock<const monitor_ptr>
+ {
+ typedef monitor_unique_lock<const monitor_ptr> base_class;
+ public:
+ template<typename Timeout>
+ scoped_timed_lock(monitor_ptr &monitor_pointer, const Timeout &timeout):
+ base_class(monitor_pointer, timeout)
+ {}
+ template<typename Timeout>
+ explicit scoped_timed_lock(const monitor_ptr<T, Mutex> &monitor_pointer, const Timeout &timeout):
+ base_class(monitor_pointer, timeout)
+ {}
+ scoped_timed_lock(monitor_ptr<T, Mutex> &monitor_pointer, bool do_lock):
+ base_class(monitor_pointer, boost::defer_lock_t())
+ {
+ if(do_lock) base_class::lock();
+ }
+ explicit scoped_timed_lock(const monitor_ptr<T, Mutex> &monitor_pointer, bool do_lock):
+ base_class(monitor_pointer, boost::defer_lock_t())
+ {
+ if(do_lock) base_class::lock();
+ }
+ };
+
+ monitor_ptr()
+ {}
+ monitor_ptr(const boost::shared_ptr<T> &smart_pointer): _pointer(smart_pointer),
+ _syncer(new detail::monitor_synchronizer<Mutex>())
+ {
+ set_monitor_ptr(_pointer.get());
+ }
+ template<typename U>
+ explicit monitor_ptr(U *pointer): _pointer(pointer),
+ _syncer(new detail::monitor_synchronizer<Mutex>())
+ {
+ set_monitor_ptr(_pointer.get());
+ }
+ // support implicit conversions
+ template<typename U>
+ monitor_ptr(const monitor_ptr<U, Mutex> &other): _pointer(other._pointer),
+ _syncer(other._syncer)
+ {}
+ // aliasing constructor
+ template<typename U>
+ monitor_ptr(const monitor_ptr<U, Mutex> &other, T *ptr):
+ _pointer(other._pointer, ptr), _syncer(other._syncer)
+ {}
+
+ virtual ~monitor_ptr() {}
+
+ monitor_unique_lock<const monitor_ptr> operator->() const
+ {
+ return monitor_unique_lock<const monitor_ptr>(*this);
+ }
+ // unlocked access
+ const boost::shared_ptr<T>& direct() const {return _pointer;}
+
+ void reset(const boost::shared_ptr<T> &smart_pointer)
+ {
+ _pointer = smart_pointer;
+ _syncer.reset(new detail::monitor_synchronizer<Mutex>());
+ set_monitor_ptr(_pointer.get());
+ };
+ template<typename U>
+ void reset(U *pointer)
+ {
+ boost::shared_ptr<T> smart_pointer(pointer);
+ reset(smart_pointer);
+ };
+ void reset()
+ {
+ _pointer.reset();
+ _syncer.reset();
+ }
+ // aliasing reset
+ template<typename U>
+ void reset(const monitor_ptr<U, Mutex> &other, T *raw_ptr)
+ {
+ _pointer.reset(other._pointer, raw_ptr);
+ _syncer = other._syncer;
+ set_monitor_ptr(_pointer.get());
+ };
+
+ operator bool() const {return _pointer;}
+
+ void swap(monitor_ptr &other)
+ {
+ using std::swap;
+ swap(_pointer, other._pointer);
+ swap(_syncer, other._syncer);
+ }
+
+ // Boost.Threads interface for Lockable concepts
+ // Lockable
+ void lock() const
+ {
+ get_syncer()->_mutex.lock();
+ }
+ bool try_lock() const
+ {
+ return get_syncer()->_mutex.try_lock();
+ }
+ void unlock() const
+ {
+ get_syncer()->_mutex.unlock();
+ }
+ // TimedLockable
+ template<typename Timeout>
+ bool timed_lock(const Timeout &timeout) const
+ {
+ return get_syncer()->_mutex.timed_lock(timeout);
+ }
+ // SharedLockable
+ void lock_shared() const
+ {
+ get_syncer()->_mutex.lock_shared();
+ }
+ bool try_lock_shared() const
+ {
+ return get_syncer()->_mutex.try_lock_shared();
+ }
+ template<typename Timeout>
+ bool timed_lock_shared(const Timeout &timeout) const
+ {
+ return get_syncer()->_mutex.timed_lock_shared(timeout);
+ }
+ void unlock_shared() const
+ {
+ get_syncer()->_mutex.unlock_shared();
+ }
+ void unlock_and_lock_shared() const
+ {
+ get_syncer()->_mutex.unlock_and_lock_shared();
+ }
+ // UpgradeLockable
+ void lock_upgrade() const
+ {
+ get_syncer()->_mutex.lock_upgrade();
+ }
+ void unlock_upgrade() const
+ {
+ get_syncer()->_mutex.unlock_upgrade();
+ }
+ void unlock_upgrade_and_lock() const
+ {
+ get_syncer()->_mutex.unlock_upgrade_and_lock();
+ }
+ void unlock_upgrade_and_lock_shared() const
+ {
+ get_syncer()->_mutex.unlock_upgrade_and_lock_shared();
+ }
+ void unlock_and_lock_upgrade() const
+ {
+ get_syncer()->_mutex.unlock_and_lock_upgrade();
+ }
+ private:
+ template<typename U, typename M>
+ friend class monitor_ptr;
+ template<typename Monitor, typename MonitorHandle, typename Lock>
+ friend class detail::lock_wrapper;
+
+ void set_monitor_ptr(const monitor_base *monitor)
+ {
+ monitor->set_synchronizer(_syncer);
+ }
+ void set_monitor_ptr(...)
+ {}
+
+ const boost::shared_ptr<detail::monitor_synchronizer<Mutex> > & get_syncer() const
+ {
+ if(!_syncer) throw boost::lock_error();
+ return _syncer;
+ }
+
+ boost::shared_ptr<T> _pointer;
+ boost::shared_ptr<detail::monitor_synchronizer<Mutex> > _syncer;
+ };
+
+ template<typename T, typename MutexA, typename MutexB>
+ inline bool operator==(const monitor_ptr<T, MutexA> &ptr0, const monitor_ptr<T, MutexB> &ptr1)
+ {
+ return ptr0.direct() == ptr1.direct();
+ }
+
+ template<typename T, typename MutexA, typename MutexB>
+ inline bool operator!=(const monitor_ptr<T, MutexA> &ptr0, const monitor_ptr<T, MutexB> &ptr1)
+ {
+ return ptr0.direct() != ptr1.direct();
+ }
+
+ template<typename T, typename MutexA, typename MutexB>
+ inline bool operator<(const monitor_ptr<T, MutexA> &ptr0, const monitor_ptr<T, MutexB> &ptr1)
+ {
+ return ptr0.direct() < ptr1.direct();
+ }
+
+ template<typename T, typename U, typename Mutex>
+ inline monitor_ptr<T, Mutex> static_pointer_cast(const monitor_ptr<U, Mutex> &pointer)
+ {
+ return monitor_ptr<T, Mutex>(pointer, static_cast<T*>(pointer.direct().get()));
+ }
+ template<typename T, typename U, typename Mutex>
+ inline monitor_ptr<T, Mutex> dynamic_pointer_cast(const monitor_ptr<U, Mutex> &pointer)
+ {
+ return monitor_ptr<T, Mutex>(pointer, dynamic_cast<T*>(pointer.direct().get()));
+ }
+ template<typename T, typename U, typename Mutex>
+ inline monitor_ptr<T, Mutex> const_pointer_cast(const monitor_ptr<U, Mutex> &pointer)
+ {
+ return monitor_ptr<T, Mutex>(pointer, const_cast<T*>(pointer.direct().get()));
+ }
+
+ template<typename T, typename Mutex>
+ void swap(poet::monitor_ptr<T, Mutex> &mon0, poet::monitor_ptr<T, Mutex> &mon1)
+ {
+ mon0.swap(mon1);
+ }
+
+ template<typename T, typename Mutex>
+ monitor_ptr<T, Mutex> & get_monitor_ptr(monitor_ptr<T, Mutex> &mon)
+ {
+ return mon;
+ }
+ template<typename T, typename Mutex>
+ const monitor_ptr<T, Mutex> & get_monitor_ptr(const monitor_ptr<T, Mutex> &mon)
+ {
+ return mon;
+ }
+};
+
+#endif // _POET_MONITOR_PTR_HPP
Added: sandbox/libpoet/trunk/poet/mutex_grapher.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/mutex_grapher.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,19 @@
+/*
+ A thread-safe singleton class which can be used build up a graph of a
+ program's locking order for mutexes, and check it for locking
+ order violations.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-10-26
+*/
+
+// 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 _POET_MUTEX_GRAPHER_HPP
+#define _POET_MUTEX_GRAPHER_HPP
+
+#include <poet/detail/mutex_grapher_decl.hpp>
+#include <poet/detail/mutex_grapher.ipp>
+
+#endif // _POET_MUTEX_GRAPHER_HPP
Added: sandbox/libpoet/trunk/poet/mutex_properties.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/mutex_properties.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,109 @@
+/*
+ A template class for getting properties of a mutex. Covers mutex types from
+ boost.thread and libpoet. Other mutex classes can provide their own
+ specializations.
+
+ begin: Frank Hess <fmhess_at_[hidden]> 2007-12-07
+*/
+
+// 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 _POET_MUTEX_PROPERTIES_HPP
+#define _POET_MUTEX_PROPERTIES_HPP
+
+namespace boost
+{
+ // forward declarations
+ class mutex;
+ class timed_mutex;
+ class recursive_mutex;
+ class recursive_timed_mutex;
+ class shared_mutex;
+};
+
+namespace poet
+{
+ enum mutex_model
+ {
+ Lockable,
+ TimedLockable,
+ SharedLockable,
+ UpgradeLockable
+ };
+
+ // forward declarations
+ template<typename Mutex, typename Key, typename KeyCompare> class acyclic_mutex;
+ template<typename T, typename Mutex> class monitor;
+ template<typename T, typename Mutex> class monitor_ptr;
+ namespace detail
+ {
+ template<typename Mutex, bool recursive, enum mutex_model model, typename Key, typename KeyCompare>
+ class specialized_acyclic_mutex;
+ };
+
+ template<typename Mutex> class mutex_properties;
+
+ template<>
+ class mutex_properties<boost::mutex>
+ {
+ public:
+ static const bool recursive = false;
+ static const mutex_model model = Lockable;
+ };
+
+ template<>
+ class mutex_properties<boost::timed_mutex>
+ {
+ public:
+ static const bool recursive = false;
+ static const mutex_model model = TimedLockable;
+ };
+
+ template<>
+ class mutex_properties<boost::recursive_mutex>
+ {
+ public:
+ static const bool recursive = true;
+ static const mutex_model model = Lockable;
+ };
+
+ template<>
+ class mutex_properties<boost::recursive_timed_mutex>
+ {
+ public:
+ static const bool recursive = true;
+ static const mutex_model model = TimedLockable;
+ };
+
+ template<>
+ class mutex_properties<boost::shared_mutex>
+ {
+ public:
+ static const bool recursive = false;
+ static const mutex_model model = UpgradeLockable;
+ };
+
+ template<typename Mutex, typename Key, typename KeyCompare>
+ class mutex_properties<poet::acyclic_mutex<Mutex, Key, KeyCompare> >:
+ public mutex_properties<Mutex>
+ {};
+
+ template<typename T, typename Mutex>
+ class mutex_properties<poet::monitor<T, Mutex> >:
+ public mutex_properties<Mutex>
+ {};
+
+ template<typename T, typename Mutex>
+ class mutex_properties<poet::monitor_ptr<T, Mutex> >:
+ public mutex_properties<Mutex>
+ {};
+
+ template<typename Mutex, bool recursive, enum mutex_model model, typename Key, typename KeyCompare>
+ class mutex_properties<detail::specialized_acyclic_mutex<Mutex, recursive, model, Key, KeyCompare> >:
+ public mutex_properties<Mutex>
+ {};
+};
+
+#endif // _POET_MUTEX_PROPERTIES_HPP
Added: sandbox/libpoet/trunk/poet/null_type.hpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/poet/null_type.hpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,22 @@
+/*
+ Type used by combiners passed to future_combining_barrier
+ as placeholders for non-existant values from future<void>s.
+
+ begin: Frank Hess <frank.hess_at_[hidden]> 2008-05-28
+*/
+
+// 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 _POET_NULL_TYPE_HPP
+#define _POET_NULL_TYPE_HPP
+
+namespace poet
+{
+ struct null_type
+ {
+ };
+}
+
+#endif //_POET_NULL_TYPE_HPP
Added: sandbox/libpoet/trunk/test/Makefile
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/Makefile 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,32 @@
+BOOST_INC_DIR=/home/fhess/svn/boost_switch
+BOOST_LIB_DIR=/home/fhess/svn/boost_switch/stage/lib
+CXX=g++
+#set CC since it is used for linking .o files by built-in rule
+CC=$(CXX)
+RM=rm -f
+LD=g++
+
+PROGRAMS = active_function_test active_object_test acyclic_mutex_test \
+ acyclic_shared_mutex_test acyclic_mutex_upgrade_lock_test \
+ exception_test future_combining_barrier_test future_selector_test \
+ future_test future_waits_test future_void_test \
+ lazy_future_test lock_move_test \
+ monitor_test new_mutex_api_test \
+ not_default_constructible_test promise_count_test timed_join_test undead_active_function_test
+
+CPPFLAGS= -pthread -I.. -I$(BOOST_INC_DIR)
+CXXFLAGS= -O0 -Wall
+LDFLAGS= -L$(BOOST_LIB_DIR) -lboost_thread-gcc43-mt -pthread
+.PHONY: all clean dep test valgrind_test
+
+all: $(PROGRAMS)
+
+clean:
+ $(RM) $(PROGRAMS)
+
+test: $(PROGRAMS)
+ (export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(BOOST_LIB_DIR); for test_prog in $(PROGRAMS); do ./$$test_prog; done;)
+
+valgrind_test: $(PROGRAMS)
+ (export LD_LIBRARY_PATH=$$LD_LIBRARY_PATH:$(BOOST_LIB_DIR); for test_prog in $(PROGRAMS); do valgrind ./$$test_prog; done;)
+
Added: sandbox/libpoet/trunk/test/active_function_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/active_function_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,122 @@
+/*
+ A test program for futures and active object classes
+
+ Author: Frank Hess <frank.hess_at_[hidden]>
+ Begin: 2005-11
+*/
+// 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 <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <functional>
+#include <iostream>
+#include <poet/active_function.hpp>
+#include <vector>
+
+int increment(int value)
+{
+// std::cerr << __FUNCTION__ << std::endl;
+ // sleep for a bit to simulate doing something nontrivial
+ boost::this_thread::sleep(boost::posix_time::millisec(100));
+ return ++value;
+}
+
+class myclass
+{
+public:
+ myclass(int value = 1): _value(value)
+ {}
+ int member_function()
+ {
+ return _value;
+ }
+private:
+ int _value;
+};
+
+void slot_tracking_test()
+{
+ static const int test_value = 5;
+ typedef poet::active_function<int ()> myfunc_type;
+ boost::shared_ptr<myclass> myobj(new myclass(test_value));
+ myfunc_type myfunc(myfunc_type::passive_slot_type(&myclass::member_function, myobj.get()).track(myobj));
+ int retval = myfunc();
+ BOOST_ASSERT(retval == test_value);
+ myobj.reset();
+ try
+ {
+ int retval;
+ retval = myfunc();
+ BOOST_ASSERT(false);
+ }
+ catch(const boost::signals2::expired_slot &)
+ {
+ }
+ catch(...)
+ {
+ assert(false);
+ }
+}
+
+void in_order_activation_queue_test()
+{
+ boost::shared_ptr<poet::in_order_activation_queue> activation_queue(new poet::in_order_activation_queue);
+ boost::shared_ptr<poet::scheduler> scheduler(new poet::scheduler(activation_queue));
+ poet::active_function<int (int)> inc(&increment, scheduler);
+ std::vector<poet::promise<int> > promises;
+ std::vector<poet::future<int> > results;
+
+ promises.push_back(poet::promise<int>());
+ results.push_back(inc(promises.back()));
+
+ promises.push_back(poet::promise<int>());
+ results.push_back(inc(promises.back()));
+
+ promises.at(1).fulfill(1);
+
+ assert(results.at(1).timed_join(boost::get_system_time() + boost::posix_time::milliseconds(100)) == false);
+ assert(results.at(0).ready() == false);
+
+ promises.at(0).fulfill(0);
+ assert(results.at(0).get() == 1);
+ assert(results.at(1).get() == 2);
+}
+
+void default_construction_test()
+{
+ poet::active_function<int (int, int)> default_constructed;
+ poet::active_function<int (int, int)> adder((std::plus<int>()));
+ default_constructed = adder;
+ assert(default_constructed(1, 2).get() == 3);
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+
+ {
+ // the bind() is only for illustration and isn't actually needed in this case,
+ // since the signatures match exactly.
+ poet::active_function<int (int)> inc1(boost::bind(&increment, _1));
+ poet::active_function<int (int)> inc2(&increment);
+ std::vector<poet::future<int> > results(2);
+ unsigned i;
+ for(i = 0; i < results.size(); ++i)
+ {
+ poet::future<unsigned> temp = inc1(i);
+ results.at(i) = inc2(temp);
+ }
+ for(i = 0; i < results.size(); ++i)
+ {
+ assert(results.at(i).get() == static_cast<int>(i + 2));
+ }
+ }
+ slot_tracking_test();
+ in_order_activation_queue_test();
+ default_construction_test();
+
+ std::cerr << "OK\n";
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/active_object_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/active_object_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,76 @@
+/*
+ A test program for futures and active object classes
+
+ Author: Frank Hess <frank.hess_at_[hidden]>
+ Begin: 2004-11
+*/
+// 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 <boost/thread.hpp>
+#include <poet/active_object.hpp>
+#include <poet/future.hpp>
+#include <iostream>
+#include <vector>
+
+class ActiveIncrementer
+{
+public:
+ poet::future<int> increment(poet::future<int> value)
+ {
+ poet::promise<int> returnValue;
+ boost::shared_ptr<IncrementRequest> request(new IncrementRequest(&_servant,
+ value, returnValue));
+ _scheduler.post_method_request(request);
+ return returnValue;
+ }
+private:
+ class Servant
+ {
+ public:
+ int increment(int value) {boost::this_thread::sleep(boost::posix_time::seconds(1)); return ++value;}
+ };
+ class IncrementRequest: public poet::method_request_base
+ {
+ public:
+ IncrementRequest(Servant *servant, poet::future<int> inputValue, poet::promise<int> returnValue):
+ _servant(servant), _inputValue(inputValue), _returnValue(returnValue)
+ {
+ }
+ virtual void run() {_returnValue.fulfill(_servant->increment(_inputValue));}
+ virtual poet::future<void> scheduling_guard() const
+ {
+ return _inputValue;
+ }
+ private:
+ Servant *_servant;
+ poet::future<int> _inputValue;
+ poet::promise<int> _returnValue;
+ };
+
+ Servant _servant;
+ poet::scheduler _scheduler;
+
+};
+
+int main()
+{
+ ActiveIncrementer inc1;
+ ActiveIncrementer inc2;
+ std::vector<poet::future<int> > results(10);
+ unsigned i;
+ std::cerr << "getting Futures..." << std::endl;
+ for(i = 0; i < 2; ++i)
+ {
+ poet::future<int> temp = inc1.increment(i);
+ results.at(i) = inc2.increment(temp);
+ }
+ std::cerr << "converting Futures to values..." << std::endl;
+ for(i = 0; i < 2; ++i)
+ {
+ int value = results.at(i);
+ std::cerr << "value from results[" << i << "] is " << value << std::endl;
+ }
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/acyclic_mutex_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/acyclic_mutex_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,67 @@
+// Test program for ayclic_mutex
+
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/shared_ptr.hpp>
+#include <cassert>
+#include <fstream>
+#include <iostream>
+#include <poet/acyclic_mutex.hpp>
+
+typedef poet::acyclic_mutex<boost::mutex> mutex_type;
+
+bool cycle_detected = false;
+
+void cycle_handler()
+{
+ cycle_detected = true;
+}
+
+int main()
+{
+ {
+ poet::mutex_grapher::scoped_lock grapher;
+ grapher->set_cycle_handler(&cycle_handler);
+ }
+ mutex_type mutex_a("a");
+ mutex_type mutex_b("b");
+ boost::shared_ptr<mutex_type> mutex_x(new mutex_type);
+ {
+ mutex_type::scoped_lock lock_a(mutex_a);
+ mutex_type::scoped_lock lock_x(*mutex_x);
+ }
+ {
+ mutex_type::scoped_lock lock_x(*mutex_x);
+ mutex_type::scoped_lock lock_b(mutex_b);
+ }
+ {
+ /* deleting the mutex and creating a new one should not
+ change the number of nodes in the mutex graph, since the
+ node for the deleted mutex should be reused. */
+ poet::mutex_grapher::scoped_lock grapher;
+ const unsigned num_nodes = boost::num_vertices(grapher->graph());
+ assert(num_nodes > 0);
+ grapher.unlock();
+
+ mutex_x.reset(new mutex_type);
+ grapher.lock();
+ assert(num_nodes == boost::num_vertices(grapher->graph()));
+ }
+ {
+ // this doesn't violate locking order, because we reset mutex_x with a new mutex
+ mutex_type::scoped_lock lock_b(mutex_b);
+ mutex_type::scoped_lock lock_x(*mutex_x);
+ assert(cycle_detected == false);
+ }
+ { /* this will violate the locking order we have established,
+ and will result in the cycle handler being called */
+ mutex_type::scoped_lock lock_x(*mutex_x);
+ mutex_type::scoped_lock lock_a(mutex_a);
+ assert(cycle_detected);
+ }
+ std::cout << __FILE__ << ": OK" << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/acyclic_mutex_upgrade_lock_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/acyclic_mutex_upgrade_lock_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,61 @@
+// Test program for ayclic_mutex
+
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/shared_ptr.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <cassert>
+#include <fstream>
+#include <iostream>
+#include <poet/acyclic_mutex.hpp>
+
+bool cycle_detected = false;
+
+struct cycle_detected_tag {};
+
+void cycle_handler()
+{
+ cycle_detected = true;
+ throw cycle_detected_tag();
+}
+
+void upgrade_test()
+{
+ {
+ poet::mutex_grapher::scoped_lock grapher;
+ grapher->set_cycle_handler(&cycle_handler);
+ }
+ typedef poet::acyclic_mutex<boost::shared_mutex> mutex_type;
+ mutex_type m;
+ {
+ boost::shared_lock<mutex_type> shared(m);
+ boost::upgrade_lock<mutex_type> upgrade(m);
+ shared.unlock();
+ {
+ boost::upgrade_to_unique_lock<mutex_type> unique(upgrade);
+ assert(cycle_detected == false);
+ }
+ try
+ {
+ boost::upgrade_lock<mutex_type> upgrade2(m);
+ assert(false);
+ }
+ catch(const struct cycle_detected_tag &)
+ {
+ }
+ catch(...)
+ {
+ assert(false);
+ }
+ }
+}
+
+int main()
+{
+ upgrade_test();
+ std::cout << __FILE__ << ": OK" << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/acyclic_shared_mutex_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/acyclic_shared_mutex_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,58 @@
+// Test program for ayclic_mutex
+
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/shared_ptr.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <cassert>
+#include <fstream>
+#include <iostream>
+#include <poet/acyclic_mutex.hpp>
+
+bool cycle_detected = false;
+
+void cycle_handler()
+{
+ cycle_detected = true;
+}
+
+void shared_mutex_wrap_test()
+{
+ {
+ poet::mutex_grapher::scoped_lock grapher;
+ grapher->set_cycle_handler(&cycle_handler);
+ }
+ typedef poet::acyclic_mutex<boost::shared_mutex> mutex_type;
+ mutex_type m;
+ mutex_type n;
+ {
+ boost::shared_lock<mutex_type> shared(m);
+ boost::upgrade_lock<mutex_type> upgrade(m);
+ shared.unlock();
+ boost::upgrade_to_unique_lock<mutex_type> unique(upgrade);
+ assert(cycle_detected == false);
+ }
+ {
+ boost::shared_lock<mutex_type> shared(m);
+ boost::shared_lock<mutex_type> shared2(n);
+ boost::shared_lock<mutex_type> shared3(m);
+ assert(cycle_detected == false);
+ }
+ {
+ boost::upgrade_lock<mutex_type> upgrade_m(m);
+ boost::unique_lock<mutex_type> unique_n(n);
+ assert(cycle_detected == false);
+ boost::upgrade_to_unique_lock<mutex_type> unique_m(upgrade_m);
+ assert(cycle_detected == true);
+ }
+}
+
+int main()
+{
+ shared_mutex_wrap_test();
+ std::cout << __FILE__ << ": OK" << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/exception_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/exception_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,153 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/assert.hpp>
+#include <iostream>
+#include <poet/active_function.hpp>
+#include <stdexcept>
+
+void throw_runtime_error()
+{
+ std::cerr << __FUNCTION__ << std::endl;
+ throw std::runtime_error("this std::runtime_error exception was transported to a future.");
+}
+
+int throw_logic_error()
+{
+ std::cerr << __FUNCTION__ << std::endl;
+ throw std::logic_error("this std::logic_error exception was transported to a future.");
+ return 0;
+}
+
+int throw_out_of_range()
+{
+ std::cerr << __FUNCTION__ << std::endl;
+ throw std::out_of_range("this std::out_of_range exception was transported to a future.");
+ return 0;
+}
+
+class custom_exception: public std::exception
+{
+public:
+ custom_exception()
+ {}
+ virtual ~custom_exception() throw() {}
+ virtual const char * what() const throw() {return "custom_exception";}
+};
+
+void throw_unknown_exception()
+{
+ std::cerr << __FUNCTION__ << std::endl;
+ throw custom_exception();
+}
+
+struct unknown
+{
+ int value;
+};
+
+void throw_really_unknown()
+{
+ std::cerr << __FUNCTION__ << std::endl;
+ throw unknown();
+}
+
+int main()
+{
+ {
+ poet::active_function<void ()> thrower(&throw_runtime_error);
+ poet::future<void> result = thrower();
+ try
+ {
+ result.get();
+ BOOST_ASSERT(false);
+ }
+ catch(const std::runtime_error &err)
+ {
+ std::cerr << "caught exception: " << err.what() << std::endl;
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ }
+
+ {
+ poet::active_function<int ()> thrower(&throw_logic_error);
+ poet::future<int> result = thrower();
+ try
+ {
+ int retval = result;
+ BOOST_ASSERT(false);
+ std::cout << "retval is " << retval << std::endl;
+ }
+ catch(const std::logic_error &err)
+ {
+ std::cerr << "caught exception: " << err.what() << std::endl;
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ }
+
+ {
+ poet::active_function<int ()> thrower(&throw_out_of_range);
+ poet::future<int> result = thrower();
+ try
+ {
+ int retval = result.get();
+ BOOST_ASSERT(false);
+ std::cout << "retval is " << retval << std::endl;
+ }
+ catch(const std::out_of_range &err)
+ {
+ std::cerr << "caught exception: " << err.what() << std::endl;
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ }
+
+ // throw an exception derived from std::exception
+ {
+ poet::active_function<void ()> thrower(&throw_unknown_exception);
+ poet::future<void> result = thrower();
+ try
+ {
+ static_cast<void>(result);
+ BOOST_ASSERT(false);
+ }
+ catch(const poet::unknown_exception &err)
+ {
+ std::cerr << "caught exception: " << err.what() << std::endl;
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ }
+
+ // throw completely unknown exception
+ {
+ poet::active_function<void ()> thrower(&throw_really_unknown);
+ poet::future<void> result = thrower();
+ try
+ {
+ static_cast<void>(result);
+ BOOST_ASSERT(false);
+ }
+ catch(const poet::unknown_exception &err)
+ {
+ std::cerr << "caught exception: " << err.what() << std::endl;
+ }
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+ }
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/future_combining_barrier_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/future_combining_barrier_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,165 @@
+// Copyright (C) Frank Mori Hess 2008
+// 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 <algorithm>
+#include <boost/tuple/tuple.hpp>
+#include <boost/variant/variant.hpp>
+#include <iterator>
+#include <poet/future_barrier.hpp>
+#include <poet/future_select.hpp>
+#include <vector>
+
+struct identity
+{
+ template<typename T>
+ const T& operator()(const T &t) const
+ {
+ return t;
+ }
+};
+
+struct tuple_creator
+{
+ template<typename T1, typename T2>
+ boost::tuple<T1, T2> operator()(const T1 &a1, const T2 &a2)
+ {
+ return boost::tuple<T1, T2>(a1, a2);
+ }
+};
+
+template<typename T1, typename T2>
+poet::future<boost::tuple<T1, T2> > operator&&(const poet::future<T1> &f1, const poet::future<T2> &f2)
+{
+ return poet::future_combining_barrier<boost::tuple<T1, T2> >(tuple_creator(), identity(), f1, f2);
+}
+
+template<typename T1, typename T2>
+poet::future<boost::variant<T1, T2> > operator||(const poet::future<T1> &f1, const poet::future<T2> &f2)
+{
+ typedef boost::variant<T1, T2> result_type;
+ poet::future<result_type> variant_f1 = poet::future_combining_barrier<result_type>(identity(), identity(), f1);
+ poet::future<result_type> variant_f2 = poet::future_combining_barrier<result_type>(identity(), identity(), f2);
+ return poet::future_select(variant_f1, variant_f2);
+}
+
+#include <cassert>
+#include <iostream>
+#include <string>
+#include <boost/variant.hpp>
+
+struct mycombiner
+{
+ template<typename Iterator>
+ int operator()(Iterator first, Iterator last)
+ {
+ return 1;
+ }
+};
+
+void barrier_exception_test()
+{
+ {
+ poet::promise<int> p1;
+ poet::future<int> f1 = p1;
+ poet::promise<int> p2;
+ poet::future<int> f2 = p2;
+ poet::future<void> result = poet::future_barrier(f1, f2);
+ p1.renege(std::runtime_error("test error"));
+ assert(result.has_exception());
+ assert(result.ready() == false);
+ try
+ {
+ result.get();
+ assert(false);
+ }
+ catch(const std::runtime_error &)
+ {}
+ }
+ // again, this time with future_combining_barrier_range
+ {
+ std::vector<poet::promise<int> > promises;
+ promises.push_back(poet::promise<int>());
+ promises.push_back(poet::promise<int>());
+ std::vector<poet::future<int> > futures;
+ std::copy(promises.begin(), promises.end(), std::back_inserter(futures));
+ poet::future<int> result = poet::future_combining_barrier_range<int>(mycombiner(), poet::detail::identity(), futures.begin(), futures.end());
+ promises.front().renege(std::runtime_error("test error"));
+ assert(result.has_exception());
+ assert(result.ready() == false);
+ try
+ {
+ result.get();
+ assert(false);
+ }
+ catch(const std::runtime_error &)
+ {}
+ }
+ // again, this time with future_combining_barrier
+ {
+ poet::promise<int> p1;
+ poet::promise<int> p2;
+ poet::future<int> f1 = p1;
+ poet::future<int> f2 = p2;
+ poet::future<boost::tuple<int, int> > result = f1 && f2;
+ p1.renege(std::runtime_error("test error"));
+ assert(result.has_exception());
+ assert(result.ready() == false);
+ try
+ {
+ result.get();
+ assert(false);
+ }
+ catch(const std::runtime_error &)
+ {}
+ }
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+
+ poet::promise<int> pi;
+ poet::promise<double> pd;
+ poet::promise<std::string> pstr;
+ poet::promise<std::string> pstr2;
+ poet::future<int> fi = pi;
+ poet::future<double> fd = pd;
+ poet::future<std::string> fstr = pstr;
+ poet::future<std::string> fstr2 = pstr2;
+
+ poet::future<boost::tuple<int, double> > fall = fi && fd;
+ poet::future<boost::variant<boost::tuple<int, double>, std::string > > fany = fall || fstr;
+ poet::future<boost::variant<boost::tuple<int, double>, std::string > > fany2 = fall || fstr2;
+
+ assert(fall.ready() == false);
+ assert(fany.ready() == false);
+ assert(fany2.ready() == false);
+
+ pi.fulfill(1);
+ assert(fall.ready() == false);
+
+ assert(fany.ready() == false);
+ assert(fstr.ready() == false);
+ pstr.fulfill("hello");
+ assert(fany.ready() == true);
+ assert(fstr.ready() == true);
+
+ assert(fall.ready() == false);
+ assert(fany2.ready() == false);
+ pd.fulfill(1.5);
+ assert(fall.ready() == true);
+ assert(fany2.ready() == true);
+
+ assert(fall.get().get<0>() == 1);
+ assert(std::abs(fall.get().get<1>() / 1.5 - 1.0) < 1e-6);
+ assert(boost::get<std::string>(fany.get()) == "hello");
+ boost::tuple<int, double> fany2_value = boost::get<boost::tuple<int, double> >(fany2.get());
+ assert(fany2_value.get<0>() == 1);
+
+ barrier_exception_test();
+
+ std::cerr << "OK" << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/future_selector_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/future_selector_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,160 @@
+#include <boost/thread.hpp>
+#include <poet/future_barrier.hpp>
+#include <poet/future_select.hpp>
+#include <cassert>
+#include <iostream>
+#include <vector>
+
+void preready_push_test()
+{
+ poet::future_selector<int> selector;
+ poet::future<int> selected_future = selector.selected();
+ assert(selector.size() == 0);
+ selector.pop_selected();
+ assert(selector.size() == -1);
+ poet::future<int> preready_future = 1;
+ selector.push(preready_future);
+ assert(selected_future.ready());
+ assert(selector.size() == 0);
+}
+
+void future_selector_scope_test()
+{
+ static const int test_value = 5;
+
+ poet::promise<int> prom;
+ poet::future<int> selected_future;
+ poet::future<int> hopeless_selected_future;
+ {
+ poet::future_selector<int> selector;
+ selected_future = selector.selected();
+ selector.pop_selected();
+ hopeless_selected_future = selector.selected();
+ selector.push(prom);
+ assert(hopeless_selected_future.has_exception() == false);
+ }
+ assert(hopeless_selected_future.has_exception() == true);
+ assert(selected_future.has_exception() == false);
+
+ assert(selected_future.ready() == false);
+ prom.fulfill(test_value);
+ assert(selected_future.ready() == true);
+ assert(selected_future.get() == test_value);
+}
+
+void future_selector_copy_test()
+{
+ std::vector<poet::promise<int> > promises;
+ promises.push_back(poet::promise<int>());
+ promises.push_back(poet::promise<int>());
+ promises.push_back(poet::promise<int>());
+
+ poet::future_selector<int> selector;
+ selector.push(promises.at(0));
+ poet::future_selector<int> selector_copy;
+ selector_copy = selector;
+ selector.push(promises.at(1));
+ selector_copy.push(promises.at(2));
+
+ assert(selector.selected().ready() == false);
+ assert(selector_copy.selected().ready() == false);
+ promises.at(0).fulfill(0);
+ assert(selector.selected().ready());
+ assert(selector.selected().get() == 0);
+ assert(selector_copy.selected().ready());
+ assert(selector_copy.selected().get() == 0);
+
+ selector.pop_selected();
+ selector_copy.pop_selected();
+
+ assert(selector.selected().ready() == false);
+ assert(selector_copy.selected().ready() == false);
+ promises.at(1).fulfill(1);
+ assert(selector.selected().ready());
+ assert(selector.selected().get() == 1);
+ assert(selector_copy.selected().ready() == false);
+
+ selector.pop_selected();
+
+ assert(selector.selected().ready() == false);
+ promises.at(2).fulfill(2);
+ assert(selector_copy.selected().ready());
+ assert(selector_copy.selected().get() == 2);
+ assert(selector.selected().ready() == false);
+}
+
+std::string converter(int)
+{
+ return "hello, world!";
+}
+
+void future_selector_other_type_push_test()
+{
+ poet::promise<int> promise;
+ poet::future_selector<std::string> selector;
+ selector.push(&converter, poet::detail::identity(), poet::future<int>(promise));
+ poet::future<std::string> future = selector.selected();
+ assert(future.ready() == false);
+ promise.fulfill(0);
+ assert(future.ready());
+ assert(future.get() == "hello, world!");
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+
+ {
+ poet::future_selector<int> selector;
+
+ std::vector<poet::promise<int> > promises;
+ promises.push_back(poet::promise<int>());
+ promises.push_back(poet::promise<int>());
+ promises.push_back(poet::promise<int>());
+
+ unsigned i;
+ for(i = 0; i < promises.size(); ++i)
+ {
+ selector.push(promises.at(i));
+ }
+ std::vector<poet::future<int> > selected_results;
+ for(i = 0; i < promises.size(); ++i)
+ {
+ selected_results.push_back(selector.selected());
+ selector.pop_selected();
+ }
+ for(i = 0; i < promises.size(); ++i)
+ {
+ selected_results.push_back(selector.selected());
+ selector.pop_selected();
+ }
+ for(i = 0; i < selected_results.size(); ++i)
+ {
+ assert(selected_results.at(i).ready() == false);
+ assert(selected_results.at(i).has_exception() == false);
+ }
+
+ assert(selected_results.at(0).ready() == false);
+ promises.at(1).fulfill(1);
+ assert(selected_results.at(0).ready() == true);
+ assert(selected_results.at(0).get() == 1);
+
+ assert(selected_results.at(1).ready() == false);
+ promises.at(0).fulfill(0);
+ assert(selected_results.at(1).ready() == true);
+ assert(selected_results.at(1).get() == 0);
+
+ assert(selected_results.at(2).ready() == false);
+ promises.at(2).fulfill(2);
+ assert(selected_results.at(2).ready() == true);
+ assert(selected_results.at(2).get() == 2);
+ }
+
+ preready_push_test();
+ future_selector_scope_test();
+ future_selector_copy_test();
+ future_selector_other_type_push_test();
+
+ std::cerr << "OK" << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/future_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/future_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,116 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <cassert>
+#include <poet/detail/identity.hpp>
+#include <poet/future_barrier.hpp>
+#include <poet/future.hpp>
+#include <iostream>
+#include <vector>
+
+static void delayed_increment(poet::promise<int> mypromise, poet::future<int> value)
+{
+ boost::this_thread::sleep(boost::posix_time::millisec(100));
+ int intValue = value;
+ ++intValue;
+ mypromise.fulfill(intValue);
+};
+
+static poet::future<int> async_delayed_increment(poet::future<int> value)
+{
+ poet::promise<int> mypromise;
+ boost::thread mythread(boost::bind(&delayed_increment, mypromise, value));
+ return mypromise;
+}
+
+// fulfill a promise with a future that is already ready
+void promise_fulfill_ready_future_test()
+{
+ static const int test_value = 4;
+ poet::promise<int> mypromise;
+ poet::future<int> myfuture = mypromise;
+ poet::future<int> fulfilling_future = test_value;
+ mypromise.fulfill(fulfilling_future);
+ assert(myfuture.ready());
+ assert(myfuture.get() == test_value);
+}
+
+// fulfill a promise with a lazy future that must be waited on to become ready
+void promise_fulfill_lazy_future_test()
+{
+ {
+ static const int test_value = 3;
+ poet::promise<int> mypromise;
+ poet::future<int> myfuture = mypromise;
+ poet::promise<int> dependency_promise;
+ poet::future<int> dependency = dependency_promise;
+ poet::future<int> lazy_fulfilling_future = poet::future_combining_barrier<int>(
+ poet::detail::identity(), poet::detail::identity(), dependency);
+ mypromise.fulfill(lazy_fulfilling_future);
+ dependency_promise.fulfill(test_value);
+ assert(myfuture.ready());
+ assert(myfuture.get() == test_value);
+ }
+ // now test promise<void> specialization
+ {
+ static const int test_value = 3;
+ poet::promise<void> mypromise;
+ poet::future<void> myfuture = mypromise;
+ poet::promise<int> dependency_promise;
+ poet::future<int> dependency = dependency_promise;
+ poet::future<int> lazy_fulfilling_future = poet::future_combining_barrier<int>(
+ poet::detail::identity(), poet::detail::identity(), dependency);
+ mypromise.fulfill(lazy_fulfilling_future);
+ dependency_promise.fulfill(test_value);
+ assert(myfuture.ready());
+ myfuture.get();
+ }
+}
+
+void future_swap_test()
+{
+ poet::future<int> a;
+ poet::promise<int> p;
+ poet::future<int> b = p;
+ using std::swap;
+ swap(a, b);
+ p.fulfill(0);
+ assert(b.ready() == false);
+ assert(a.ready());
+ a.swap(b);
+ assert(a.ready() == false);
+ assert(b.ready());
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+
+ std::vector<poet::future<int> > futures;
+ unsigned i;
+ for(i = 0; i < 10; ++i)
+ {
+ if(i == 0)
+ {
+ futures.push_back(async_delayed_increment(0));
+ }else
+ {
+ futures.push_back(async_delayed_increment(futures.at(i - 1)));
+ }
+ }
+ for(i = 0; i < 10; ++i)
+ {
+ assert(futures.at(i).get() == static_cast<int>(i + 1));
+ }
+
+ promise_fulfill_ready_future_test();
+ promise_fulfill_lazy_future_test();
+ future_swap_test();
+
+ std::cerr << "OK\n";
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/future_void_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/future_void_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,44 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <poet/future.hpp>
+#include <iostream>
+#include <stdexcept>
+
+int main()
+{
+ {
+ poet::future<double> fut(5.);
+ poet::future<void> void_fut = fut;
+ BOOST_ASSERT(void_fut.ready());
+ BOOST_ASSERT(void_fut.has_exception() == false);
+ }
+ {
+ poet::future<double> uncertain_fut;
+ poet::future<void> void_uncertain_fut = uncertain_fut;
+ BOOST_ASSERT(void_uncertain_fut.ready() == false);
+ BOOST_ASSERT(void_uncertain_fut.has_exception());
+ }
+ {
+ poet::promise<int> mypromise;
+ poet::promise<void> void_promise = mypromise;
+ poet::promise<void> void_promise_too = void_promise;
+ poet::future<int> fut(mypromise);
+ BOOST_ASSERT(fut.ready() == false);
+ BOOST_ASSERT(fut.has_exception() == false);
+ try
+ {
+ void_promise.fulfill();
+ BOOST_ASSERT(false);
+ }
+ catch(const std::invalid_argument &)
+ {}
+ void_promise_too.renege(std::runtime_error("reneged on promise"));
+ BOOST_ASSERT(fut.ready() == false);
+ BOOST_ASSERT(fut.has_exception() == true);
+ }
+ std::cout << "Test passed." << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/future_waits_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/future_waits_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,287 @@
+// Copyright (C) Frank Mori Hess 2007-2008
+// 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 <boost/bind.hpp>
+#include <boost/date_time/posix_time/posix_time.hpp>
+#include <boost/function.hpp>
+#include <boost/thread.hpp>
+#include <boost/tuple/tuple.hpp>
+#include <iostream>
+#include <poet/detail/identity.hpp>
+#include <poet/future_barrier.hpp>
+#include <poet/future_select.hpp>
+#include <utility>
+#include <vector>
+
+void get_future(poet::future<void> f)
+{
+ f.get();
+}
+
+void myslot(bool *ran)
+{
+ *ran = true;
+}
+
+
+class my_iterating_combiner
+{
+public:
+ my_iterating_combiner(unsigned *sum): _sum(sum)
+ {}
+ template<typename Iterator>
+ unsigned operator()(Iterator begin, Iterator end)
+ {
+ Iterator it;
+ for(it = begin; it != end; ++it)
+ {
+ *_sum += *it;
+ }
+ return *_sum;
+ }
+private:
+ unsigned *_sum;
+};
+
+boost::tuple<unsigned, double> my_hetero_combiner(unsigned arg1, poet::null_type, double arg3)
+{
+ boost::tuple<unsigned, double> result;
+ result.get<0>() = arg1;
+ result.get<1>() = arg3;
+ return result;
+}
+
+void combining_barrier_test()
+{
+ {
+ std::vector<poet::promise<double> > promises;
+ promises.push_back(poet::promise<double>());
+ promises.push_back(poet::promise<double>());
+ std::vector<poet::future<void> > futures;
+ std::copy(promises.begin(), promises.end(), std::back_inserter(futures));
+ bool combiner_run_flag = false;
+ poet::future<void> all_ready = poet::future_combining_barrier_range<void>(
+ boost::bind(&myslot, &combiner_run_flag), poet::detail::identity(), futures.begin(), futures.end());
+ assert(all_ready.ready() == false);
+ assert(combiner_run_flag == false);
+ assert(all_ready.has_exception() == false);
+ promises.at(0).fulfill(1.0);
+ assert(all_ready.ready() == false);
+ assert(combiner_run_flag == false);
+ assert(all_ready.has_exception() == false);
+ promises.at(1).fulfill(2);
+ assert(all_ready.ready() == true);
+ assert(combiner_run_flag == true);
+ assert(all_ready.has_exception() == false);
+ }
+ // similar, but input futures not converted to void before passing to future_combining_barrier
+ {
+ std::vector<poet::promise<unsigned> > promises;
+ promises.push_back(poet::promise<unsigned>());
+ promises.push_back(poet::promise<unsigned>());
+ std::vector<poet::future<unsigned> > futures;
+ std::copy(promises.begin(), promises.end(), std::back_inserter(futures));
+ unsigned combiner_sum = 0;
+ poet::future<void> all_ready = poet::future_combining_barrier_range<void>(
+ my_iterating_combiner(&combiner_sum), poet::detail::identity(), futures.begin(), futures.end());
+ assert(all_ready.ready() == false);
+ assert(combiner_sum == 0);
+ assert(all_ready.has_exception() == false);
+ promises.at(0).fulfill(1);
+ assert(all_ready.ready() == false);
+ assert(combiner_sum == 0);
+ assert(all_ready.has_exception() == false);
+ promises.at(1).fulfill(2);
+ assert(all_ready.ready() == true);
+ assert(all_ready.has_exception() == false);
+ assert(combiner_sum == futures.at(0).get() + futures.at(1).get());
+ }
+ // similar, but now with non-void result type
+ {
+ std::vector<poet::promise<unsigned> > promises;
+ promises.push_back(poet::promise<unsigned>());
+ promises.push_back(poet::promise<unsigned>());
+ std::vector<poet::future<unsigned> > futures;
+ std::copy(promises.begin(), promises.end(), std::back_inserter(futures));
+ unsigned combiner_sum = 0;
+ poet::future<unsigned> all_ready = poet::future_combining_barrier_range<unsigned>(
+ my_iterating_combiner(&combiner_sum), poet::detail::identity(), futures.begin(), futures.end());
+ assert(all_ready.ready() == false);
+ assert(combiner_sum == 0);
+ assert(all_ready.has_exception() == false);
+ promises.at(0).fulfill(1);
+ assert(all_ready.ready() == false);
+ assert(combiner_sum == 0);
+ assert(all_ready.has_exception() == false);
+ promises.at(1).fulfill(2);
+ assert(all_ready.ready() == true);
+ assert(all_ready.has_exception() == false);
+ assert(combiner_sum == futures.at(0).get() + futures.at(1).get());
+ assert(all_ready.get() == combiner_sum);
+ }
+ // now with heterogeneous inputs
+ {
+ static const unsigned unsigned_test_value = 1;
+ static const double double_test_value = 1.5;
+ static const double epsilon = 1e-6;
+
+ poet::promise<unsigned> promise0;
+ poet::promise<void> promise1;
+ poet::promise<double> promise2;
+ poet::future<unsigned> future0 = promise0;
+ poet::future<void> future1 = promise1;
+ poet::future<double> future2 = promise2;
+ poet::future<boost::tuple<unsigned, double> > all_ready =
+ poet::future_combining_barrier<boost::tuple<unsigned, double> >(
+ &my_hetero_combiner, poet::detail::identity(), future0, future1, future2);
+ assert(all_ready.ready() == false);
+ assert(all_ready.has_exception() == false);
+ promise0.fulfill(unsigned_test_value);
+ assert(all_ready.ready() == false);
+ assert(all_ready.has_exception() == false);
+ promise2.fulfill(double_test_value);
+ assert(all_ready.ready() == false);
+ assert(all_ready.has_exception() == false);
+ promise1.fulfill();
+ assert(all_ready.ready() == true);
+ assert(all_ready.has_exception() == false);
+ assert(all_ready.get().get<0>() == unsigned_test_value);
+ assert(std::abs(all_ready.get().get<1>() / double_test_value - 1.0) < epsilon);
+ }
+}
+
+void select_none_test()
+{
+ std::vector<poet::future<int> > futures;
+ poet::future<int> selected_future = poet::future_select_range(futures.begin(), futures.end());
+ assert(selected_future.ready() == false);
+ assert(selected_future.has_exception());
+ try
+ {
+ selected_future.get();
+ assert(false);
+ }
+ catch(const poet::uncertain_future&)
+ {}
+ catch(...)
+ {
+ assert(false);
+ }
+}
+
+void barrier_none_test()
+{
+ {
+ std::vector<poet::future<int> > futures;
+ poet::future<void> result = poet::future_barrier_range(futures.begin(), futures.end());
+ assert(result.ready());
+ assert(result.has_exception() == false);
+ try
+ {
+ result.get();
+ }
+ catch(...)
+ {
+ assert(false);
+ }
+ }
+ // again, but with future_combining_barrier_range
+ {
+ std::vector<poet::future<unsigned> > futures;
+ unsigned sum = 0;
+ poet::future<unsigned> result = poet::future_combining_barrier_range<unsigned>(my_iterating_combiner(&sum),
+ poet::detail::identity(),
+ futures.begin(), futures.end());
+ assert(result.ready());
+ assert(result.has_exception() == false);
+ try
+ {
+ assert(result.get() == sum);
+ }
+ catch(...)
+ {
+ assert(false);
+ }
+ }
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+ {
+ poet::promise<double> x_promise;
+ poet::future<double> x(x_promise);
+ poet::promise<short> y_promise;
+ poet::future<short> y(y_promise);
+ poet::future<void> all_ready = poet::future_barrier(x, y);
+ assert(all_ready.ready() == false);
+ assert(all_ready.has_exception() == false);
+ boost::thread blocking_thread(boost::bind(&get_future, all_ready));
+ boost::this_thread::sleep(boost::posix_time::millisec(200));
+ x_promise.fulfill(1.0);
+ assert(all_ready.ready() == false);
+ assert(all_ready.has_exception() == false);
+ bool thread_done = blocking_thread.timed_join(boost::get_system_time());
+ assert(thread_done == false);
+ y_promise.fulfill(2);
+ assert(all_ready.ready() == true);
+ assert(all_ready.has_exception() == false);
+ blocking_thread.join();
+ }
+
+ {
+ poet::promise<short> x_promise;
+ poet::future<short> x(x_promise);
+ poet::promise<short> y_promise;
+ poet::future<short> y(y_promise);
+ poet::future<short> any_ready = poet::future_select(x, y);
+ assert(any_ready.ready() == false);
+ assert(any_ready.has_exception() == false);
+ boost::thread blocking_thread(boost::bind(&get_future, any_ready));
+ boost::this_thread::sleep(boost::posix_time::millisec(200));
+ bool thread_done = blocking_thread.timed_join(boost::get_system_time());
+ assert(thread_done == false);
+ assert(any_ready.ready() == false);
+ assert(any_ready.has_exception() == false);
+ static const short x_value = 1;
+ x_promise.fulfill(x_value);
+ assert(any_ready.ready() == true);
+ assert(any_ready.has_exception() == false);
+ blocking_thread.join();
+ y_promise.fulfill(2);
+ assert(any_ready.ready() == true);
+ assert(any_ready.has_exception() == false);
+ assert(any_ready.get() == x_value);
+ }
+
+ {
+ poet::promise<short> x_promise;
+ poet::future<short> x(x_promise);
+ poet::promise<double> y_promise;
+ poet::future<double> y(y_promise);
+ poet::future<void> any_ready = poet::future_select<void>(x, y);
+ assert(any_ready.ready() == false);
+ assert(any_ready.has_exception() == false);
+ boost::thread blocking_thread(boost::bind(&get_future, any_ready));
+ boost::this_thread::sleep(boost::posix_time::millisec(200));
+ bool thread_done = blocking_thread.timed_join(boost::get_system_time());
+ assert(thread_done == false);
+ static const short x_value = 1;
+ x_promise.fulfill(x_value);
+ assert(any_ready.ready() == true);
+ assert(any_ready.has_exception() == false);
+ blocking_thread.join();
+ y_promise.fulfill(2.0);
+ assert(any_ready.ready() == true);
+ assert(any_ready.has_exception() == false);
+ }
+
+ combining_barrier_test();
+ select_none_test();
+ barrier_none_test();
+
+ std::cerr << "OK\n";
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/lazy_future_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/lazy_future_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,84 @@
+// Copyright (C) Frank Mori Hess 2008
+// 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 <cassert>
+#include <poet/future_barrier.hpp>
+#include <poet/future_select.hpp>
+#include <poet/detail/identity.hpp>
+#include <iostream>
+
+
+int should_not_run(int )
+{
+ assert(false);
+ return 0;
+}
+
+int negate(int x)
+{
+ return -x;
+}
+
+void lazy_future_select_test()
+{
+ static const int test_value = 3;
+
+ poet::promise<int> p0;
+ poet::future<int> f0 = p0;
+ poet::future<int> f0_combined = poet::future_combining_barrier<int>(&negate, poet::detail::identity(), f0);
+
+ poet::promise<int> p1;
+ poet::future<int> f1 = p1;
+ poet::future<int> f1_combined = poet::future_combining_barrier<int>(&should_not_run, poet::detail::identity(), f1);
+
+ poet::future<int> fany = poet::future_select(f0_combined, f1_combined);
+ p0.fulfill(test_value);
+ assert(fany.ready());
+ assert(fany.get() == -test_value);
+
+ p1.fulfill(1);
+ // further usage of fany should not result in f1_combined being waited on or its combiner running
+ fany.ready();
+ fany.get();
+}
+
+// same as lazy_future_select_test except using future_selector object instead of future_select function
+void lazy_future_selector_test()
+{
+ static const int test_value = 3;
+
+ poet::promise<int> p0;
+ poet::future<int> f0 = p0;
+ poet::future<int> f0_combined = poet::future_combining_barrier<int>(&negate, poet::detail::identity(), f0);
+
+ poet::promise<int> p1;
+ poet::future<int> f1 = p1;
+ poet::future<int> f1_combined = poet::future_combining_barrier<int>(&should_not_run, poet::detail::identity(), f1);
+
+ poet::future_selector<int> fany;
+ fany.push(f1_combined);
+ fany.push(f0_combined);
+
+ p0.fulfill(test_value);
+ assert(fany.selected().ready());
+ assert(fany.selected().get() == -test_value);
+
+ p1.fulfill(1);
+ /* further usage of completed future from fany.selected() should not result in
+ f1_combined being waited on or its combiner running */
+ fany.selected().ready();
+ fany.selected().get();
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+
+ lazy_future_select_test();
+ lazy_future_selector_test();
+
+ std::cerr << "OK\n";
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/lock_move_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/lock_move_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,22 @@
+#include <poet/monitor.hpp>
+#include <poet/monitor_locks.hpp>
+#include <cassert>
+
+poet::monitor_unique_lock<poet::monitor<int> > get_lock(poet::monitor<int> & m)
+{
+ return poet::monitor_unique_lock<poet::monitor<int> >(m);
+}
+
+void test_unique_lock_move_from_rvalue_on_construction()
+{
+ poet::monitor<int> m;
+ poet::monitor_unique_lock<poet::monitor<int> > l(get_lock(m));
+ assert(l.owns_lock());
+ assert(l.mutex()==&m);
+}
+
+int main()
+{
+ test_unique_lock_move_from_rvalue_on_construction();
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/monitor_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/monitor_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,365 @@
+// An example of using the monitor_ptr and monitor classes
+// for automatically locked access to an object.
+
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/bind.hpp>
+#include <boost/ref.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <cmath>
+#include <iostream>
+#include <poet/monitor.hpp>
+#include <poet/monitor_ptr.hpp>
+#include <poet/monitor_base.hpp>
+#include <utility>
+
+int step_counter;
+
+void check_step(int expected)
+{
+ std::cerr << " " << expected;
+ assert(step_counter++ == expected);
+}
+
+class Monitored: public poet::monitor_base
+{
+public:
+ Monitored(): value(0)
+ {}
+ void waiting_function()
+ {
+ check_step(0);
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ check_step(1);
+ wait();
+ check_step(4);
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ check_step(5);
+ }
+ void notifying_function()
+ {
+ check_step(2);
+ notify_all();
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ check_step(3);
+ }
+ void another_function()
+ {
+ check_step(6);
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ check_step(7);
+ }
+ int value;
+};
+
+//test for poet::monitor_ptr
+
+typedef poet::monitor_ptr<Monitored> monitor_ptr_type;
+
+void monitor_ptr_thread0_function(monitor_ptr_type mymonitor)
+{
+ mymonitor->waiting_function();
+}
+
+void monitor_ptr_thread1_function(monitor_ptr_type mymonitor)
+{
+ boost::this_thread::sleep(boost::posix_time::millisec(500));
+ mymonitor->notifying_function();
+ boost::this_thread::sleep(boost::posix_time::millisec(500));
+ mymonitor->another_function();
+}
+
+void monitor_ptr_comparison_test()
+{
+ poet::monitor_ptr<char> mymon0(new char);
+ poet::monitor_ptr<char> mymon0_copy = mymon0;
+ poet::monitor_ptr<char> mymon1(new char);
+ poet::monitor_ptr<char> mymon_null;
+ assert(mymon_null == 0);
+ assert(mymon_null != mymon0);
+ assert(mymon_null != mymon1);
+ assert(mymon0 != mymon1);
+ assert(mymon0 == mymon0_copy);
+ assert((mymon0 < mymon1 && !(mymon0 > mymon1)) || (mymon0 > mymon1 && !(mymon0 < mymon1)));
+}
+
+// make sure we can compile when using const monitor_ptr
+void monitor_ptr_const_test()
+{
+ typedef poet::monitor_ptr<Monitored, boost::timed_mutex> mon_type;
+ static const int test_value = 1;
+ const mon_type mymon(new Monitored());
+ mymon->value = test_value;
+ assert(mymon->value == test_value);
+ {
+ const mon_type::scoped_lock lock(mymon);
+ assert(lock->value == test_value);
+ }
+ {
+ const mon_type::scoped_try_lock lock(mymon);
+ assert(lock->value == test_value);
+ }
+ {
+ const mon_type::scoped_timed_lock lock(mymon, true);
+ assert(lock->value == test_value);
+ }
+}
+
+class MyBase
+{
+public:
+ virtual ~MyBase() {};
+ virtual void set(int value) = 0;
+ virtual int get() const = 0;
+};
+
+class MyDerived: public MyBase
+{
+public:
+ MyDerived(): _value(0)
+ {}
+ virtual void set(int value)
+ {
+ _value = value;
+ }
+ virtual int get() const
+ {
+ return _value;
+ }
+private:
+ int _value;
+};
+
+class MyDerivedToo: public MyBase
+{
+public:
+ MyDerivedToo()
+ {}
+ virtual void set(int value)
+ {
+ }
+ virtual int get() const
+ {
+ return 2;
+ }
+private:
+};
+
+
+void monitor_ptr_cast_test()
+{
+ static const int test_value = 2;
+ poet::monitor_ptr<MyBase> mon_base(new MyDerived());
+ mon_base->set(test_value);
+
+ poet::monitor_ptr<MyDerived> mon_derived = poet::static_pointer_cast<MyDerived>(mon_base);
+ assert(mon_derived->get() == test_value);
+ mon_base = poet::static_pointer_cast<MyBase>(mon_derived);
+ assert(mon_base->get() == test_value);
+
+ mon_derived = poet::dynamic_pointer_cast<MyDerived>(mon_base);
+ assert(mon_derived);
+ assert(mon_derived->get() == test_value);
+ mon_base = poet::dynamic_pointer_cast<MyBase>(mon_derived);
+ assert(mon_base);
+ assert(mon_base->get() == test_value);
+ poet::monitor_ptr<MyDerivedToo> mon_derived_too = poet::dynamic_pointer_cast<MyDerivedToo>(mon_base);
+ assert(mon_derived_too == 0);
+
+ poet::monitor_ptr<const MyBase> mon_base_const = mon_base;
+ assert(mon_base_const->get() == test_value);
+ mon_base = poet::const_pointer_cast<MyBase>(mon_base);
+ assert(mon_base->get() == test_value);
+}
+
+struct point
+{
+ point(int x_val = 0, int y_val = 0): x(x_val), y(y_val)
+ {}
+ int x;
+ int y;
+};
+
+void monitor_ptr_aliasing_constructor_test()
+{
+ poet::monitor_ptr<point> mypoint(new point());
+ mypoint->x = 1;
+ poet::monitor_ptr<int> int_pointer(mypoint, &mypoint->x);
+ {
+ poet::monitor_ptr<int>::scoped_lock x_lock(int_pointer);
+ *x_lock = 2;
+ }
+ assert(mypoint->x == 2);
+ int_pointer.reset(mypoint, &mypoint->y);
+ point *plain_old_pointer = mypoint.direct().get();
+ mypoint.reset();
+ {
+ poet::monitor_ptr<int>::scoped_lock y_lock(int_pointer);
+ *y_lock = 3;
+ }
+ assert(plain_old_pointer->y == 3);
+}
+
+void monitor_ptr_test()
+{
+ std::cerr << __FUNCTION__;
+ monitor_ptr_comparison_test();
+ monitor_ptr_const_test();
+ monitor_ptr_cast_test();
+ monitor_ptr_aliasing_constructor_test();
+
+ step_counter = 0;
+ monitor_ptr_type mymonitor(new Monitored);
+ monitor_ptr_type mymonitor_too(mymonitor);
+ swap(mymonitor, mymonitor_too);
+ boost::thread thread0(boost::bind(&monitor_ptr_thread0_function, mymonitor));
+ boost::thread thread1(boost::bind(&monitor_ptr_thread1_function, mymonitor));
+ thread0.join();
+ thread1.join();
+ std::cerr << " OK" << std::endl;
+}
+
+
+// same thing done with poet::monitor
+
+typedef poet::monitor<Monitored> monitor_type;
+
+void monitor_thread0_function(monitor_type &mymonitor)
+{
+ monitor_type::scoped_lock mon_lock(mymonitor);
+ mon_lock->waiting_function();
+}
+
+void monitor_thread1_function(monitor_type &mymonitor)
+{
+ boost::this_thread::sleep(boost::posix_time::millisec(500));
+ {
+ monitor_type::scoped_lock mon_lock(mymonitor);
+ mon_lock->notifying_function();
+ }
+ boost::this_thread::sleep(boost::posix_time::millisec(500));
+ {
+ monitor_type::scoped_lock mon_lock(mymonitor);
+ mon_lock->another_function();
+ }
+}
+
+// make sure we can compile when using const monitor_ptr
+void monitor_const_test()
+{
+ typedef poet::monitor<Monitored, boost::timed_mutex> mon_type;
+ static const int test_value = 1;
+ const mon_type mymon = Monitored();
+ {
+ const mon_type::scoped_lock lock(mymon);
+ lock->value = test_value;
+ assert(lock->value == test_value);
+ }
+ {
+ const mon_type::scoped_try_lock lock(mymon);
+ assert(lock->value == test_value);
+ }
+ {
+ const mon_type::scoped_timed_lock lock(mymon, true);
+ assert(lock->value == test_value);
+ }
+}
+
+void monitor_construction_test()
+{
+ static const int first_test_value = -1;
+ static const double second_test_value = 1.5;
+ typedef poet::monitor<std::pair<int, double> > my_monitor_type;
+ // construction of value by forwarding arguments to value constructor
+ my_monitor_type mymon(first_test_value, second_test_value);
+ {
+ my_monitor_type::scoped_lock lock(mymon);
+ assert(lock->first == first_test_value);
+ assert(std::abs(lock->second - second_test_value) < 1e-6);
+ }
+ // copy-construction
+ my_monitor_type mymon_too(mymon);
+ {
+ my_monitor_type::scoped_lock lock(mymon);
+ my_monitor_type::scoped_lock lock_too(mymon_too);
+ assert(lock_too->first == first_test_value);
+ assert(std::abs(lock_too->second - second_test_value) < 1e-6);
+ }
+
+}
+
+void monitor_assignment_test()
+{
+ static const int test_value = 3;
+ poet::monitor<int> mymon;
+ poet::monitor<int> mymon_too;
+ mymon = test_value;
+ {
+ poet::monitor<int>::scoped_lock lock(mymon);
+ assert(*lock == test_value);
+ }
+ mymon_too = mymon;
+ {
+ poet::monitor<int>::scoped_lock lock_too(mymon_too);
+ assert(*lock_too == test_value);
+ static const int test_value_too = 5;
+ *lock_too = test_value_too;
+ assert(*lock_too == test_value_too);
+ // make sure we really did a deep copy
+ poet::monitor<int>::scoped_lock lock(mymon);
+ assert(*lock == test_value);
+ }
+}
+
+void monitor_to_monitor_ptr_test()
+{
+ static const int test_value = 4;
+ poet::monitor<point> mymon;
+ mymon->x = test_value;
+ poet::monitor_ptr<point> mymon_ptr = mymon.get_monitor_ptr();
+ assert(mymon_ptr->x == test_value);
+
+ {
+ const poet::monitor<point> const_mymon(test_value, 0);
+ poet::monitor_ptr<const point> const_mymon_ptr = const_mymon.get_monitor_ptr();
+ assert(const_mymon_ptr->x == test_value);
+ assert(const_mymon->x == test_value);
+ }
+
+ {
+ poet::monitor<const point> const_mymon(test_value, 0);
+ poet::monitor_ptr<const point> const_mymon_ptr = const_mymon.get_monitor_ptr();
+ assert(const_mymon_ptr->x == test_value);
+ assert(const_mymon->x == test_value);
+ }
+}
+
+void monitor_test()
+{
+ std::cerr << __FUNCTION__;
+ monitor_const_test();
+ monitor_construction_test();
+ monitor_assignment_test();
+ monitor_to_monitor_ptr_test();
+
+ step_counter = 0;
+ monitor_type mymonitor;
+ monitor_type mymonitor_too;
+ swap(mymonitor, mymonitor_too);
+ boost::thread thread0(boost::bind(&monitor_thread0_function, boost::ref(mymonitor)));
+ boost::thread thread1(boost::bind(&monitor_thread1_function, boost::ref(mymonitor)));
+ thread0.join();
+ thread1.join();
+ std::cerr << " OK" << std::endl;
+}
+
+int main(int argc, const char **argv)
+{
+ monitor_ptr_test();
+ monitor_test();
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/new_mutex_api_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/new_mutex_api_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,381 @@
+// Some tests for new mutex api based on Boost.Thread 1.35.0
+
+// Copyright (C) Frank Mori Hess 2008
+// 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 <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include <poet/acyclic_mutex.hpp>
+#include <poet/monitor.hpp>
+#include <poet/monitor_ptr.hpp>
+#include <poet/monitor_base.hpp>
+
+struct point
+{
+ point(int init_x = 0, int init_y = 0):
+ x(init_x), y(init_y)
+ {}
+ void const_function() const {};
+ void nonconst_function() {};
+ int x;
+ int y;
+};
+
+void monitor_unique_lock_test()
+{
+ static const int test_value = 5;
+ {
+ typedef poet::monitor_ptr<int> monitor_type;
+ monitor_type mon(new int(test_value));
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ assert(*lock == test_value);
+ }
+ {
+ typedef poet::monitor_ptr<point> monitor_type;
+ monitor_type mon(new point(test_value));
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ assert(lock->x == test_value);
+ }
+ {
+ typedef poet::monitor<int> monitor_type;
+ monitor_type mon(test_value);
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ assert(*lock == test_value);
+ }
+ {
+ typedef poet::monitor<point> monitor_type;
+ monitor_type mon = point(test_value);
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ assert(lock->x == test_value);
+ }
+#if 0
+// the following should not compile, due to violating constness
+ {
+ typedef poet::monitor_ptr<const point> monitor_type;
+ monitor_type mon(new point(test_value));
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ lock->nonconst_function();
+ }
+#endif
+ {
+ typedef poet::monitor_ptr<const point> monitor_type;
+ monitor_type mon(new point(test_value));
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ lock->const_function();
+ }
+#if 0
+// the following should not compile, due to violating constness
+ {
+ typedef const poet::monitor<point> monitor_type;
+ monitor_type mon = point(test_value);
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ lock->nonconst_function();
+ }
+#endif
+ {
+ typedef const poet::monitor<point> monitor_type;
+ monitor_type mon = point(test_value);
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ lock->const_function();
+ }
+#if 0
+// the following should not compile, due to violating constness
+ {
+ typedef poet::monitor<const point> monitor_type;
+ monitor_type mon = point(test_value);
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ lock->nonconst_function();
+ }
+#endif
+ {
+ typedef poet::monitor<const point> monitor_type;
+ monitor_type mon = point(test_value);
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ lock->const_function();
+ }
+ {
+ try
+ {
+ typedef poet::monitor_ptr<int> monitor_type;
+ monitor_type mon;
+ // locking an empty monitor_ptr throws
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ assert(false);
+ }
+ catch(const boost::lock_error &)
+ {}
+ }
+}
+
+void monitor_rw_lock_test()
+{
+ static const int test_value = 3;
+ {
+ typedef poet::monitor<point, boost::shared_mutex> monitor_type;
+ monitor_type mon = point(test_value);
+ poet::monitor_shared_lock<monitor_type> shared(mon);
+ assert(shared->x == test_value);
+ shared->const_function();
+ poet::monitor_upgrade_lock<monitor_type> upgrade(mon);
+ shared.unlock();
+ poet::monitor_upgrade_to_unique_lock<monitor_type> unique(upgrade);
+ unique->const_function();
+ unique->nonconst_function();
+ }
+}
+
+// monitor and monitor_ptr should be useable with Boost.Thread locks
+void lockable_concept_test()
+{
+ {
+ typedef poet::monitor_ptr<int> monitor_type;
+ monitor_type mon(new int(0));
+ {
+ boost::lock_guard<monitor_type> lock(mon);
+ }
+ {
+ boost::unique_lock<monitor_type> lock(mon);
+ }
+ }
+ {
+ typedef poet::monitor_ptr<int, boost::shared_mutex> monitor_type;
+ monitor_type mon(new int(0));
+ {
+ boost::shared_lock<monitor_type> shared(mon);
+ boost::upgrade_lock<monitor_type> upgrade(mon);
+ shared.unlock();
+ boost::upgrade_to_unique_lock<monitor_type> unique(upgrade);
+ }
+ }
+ {
+ typedef poet::monitor<int> monitor_type;
+ monitor_type mon(0);
+ {
+ boost::lock_guard<monitor_type> lock(mon);
+ }
+ {
+ boost::unique_lock<monitor_type> lock(mon);
+ }
+ }
+ {
+ typedef poet::monitor<int, boost::shared_mutex> monitor_type;
+ monitor_type mon(0);
+ {
+ boost::shared_lock<monitor_type> shared(mon);
+ boost::upgrade_lock<monitor_type> upgrade(mon);
+ shared.unlock();
+ boost::upgrade_to_unique_lock<monitor_type> unique(upgrade);
+ }
+ }
+}
+
+template<typename Lock1, typename Lock2, typename Monitor>
+void monitor_lock_move_test(Monitor &mon)
+{
+ {
+ Lock1 lock1(mon);
+ Lock2 lock2(mon, boost::defer_lock_t());
+ assert(lock1.owns_lock());
+ assert(lock2.owns_lock() == false);
+ lock2 = lock1.move();
+ assert(lock2.owns_lock());
+ assert(lock2.mutex() == &mon);
+ }
+ {
+ Lock1 lock1(mon);
+ assert(lock1.owns_lock());
+ Lock2 lock2(move(lock1));
+ assert(lock1.owns_lock() == false);
+ assert(lock2.owns_lock());
+ assert(lock2.mutex() == &mon);
+ }
+}
+
+template<typename Lock, typename Monitor>
+void monitor_temp_lock_move_test(Monitor &mon)
+{
+ Lock lock = Lock(mon);
+ assert(lock.owns_lock());
+}
+
+template<typename Lock, typename Monitor>
+void monitor_swap_test()
+{
+ Monitor mon1;
+ Lock lock1(mon1);
+ Monitor mon2;
+ Lock lock2(mon2);
+
+ using std::swap;
+ swap(lock1, lock2);
+ assert(lock1.owns_lock());
+ assert(lock1.mutex() == &mon2);
+ assert(lock2.owns_lock());
+ assert(lock2.mutex() == &mon1);
+
+ lock1.swap(lock2);
+ assert(lock1.owns_lock());
+ assert(lock1.mutex() == &mon1);
+ assert(lock2.owns_lock());
+ assert(lock2.mutex() == &mon2);
+}
+
+void upgrade_to_unique_move_test()
+{
+ typedef poet::monitor<int, boost::shared_mutex> monitor_type;
+ monitor_type mon1;
+ monitor_type mon2;
+ {
+ poet::monitor_upgrade_lock<monitor_type> upgrade1(mon1);
+ poet::monitor_upgrade_to_unique_lock<monitor_type> lock1(upgrade1);
+ assert(lock1.owns_lock());
+ poet::monitor_upgrade_lock<monitor_type> upgrade2(mon2);
+ poet::monitor_upgrade_to_unique_lock<monitor_type> lock2(upgrade2);
+ lock2 = move(lock1);
+ assert(lock1.owns_lock() == false);
+ assert(lock2.owns_lock());
+ }
+ {
+ poet::monitor_upgrade_lock<monitor_type> upgrade1(mon1);
+ poet::monitor_upgrade_to_unique_lock<monitor_type> lock1(upgrade1);
+ assert(lock1.owns_lock());
+ poet::monitor_upgrade_to_unique_lock<monitor_type> lock2(lock1.move());
+ assert(lock1.owns_lock() == false);
+ assert(lock2.owns_lock());
+ }
+ {
+ poet::monitor_upgrade_lock<monitor_type> upgrade1(mon1);
+ poet::monitor_upgrade_to_unique_lock<monitor_type> lock1(upgrade1);
+ assert(lock1.owns_lock());
+ poet::monitor_upgrade_lock<monitor_type> upgrade2(mon2);
+ poet::monitor_upgrade_to_unique_lock<monitor_type> lock2(upgrade2);
+ assert(lock2.owns_lock());
+ using std::swap;
+ swap(lock1, lock2);
+ assert(lock1.owns_lock());
+ assert(lock2.owns_lock());
+ }
+}
+
+void double_move_test()
+{
+ typedef poet::monitor<int, boost::shared_mutex> monitor_type;
+ monitor_type mon1;
+ poet::monitor_unique_lock<monitor_type> lock1(mon1);
+ monitor_type mon2;
+ poet::monitor_unique_lock<monitor_type> lock2(mon2);
+ lock2 = move(move(lock1));
+ assert(lock1.owns_lock() == false);
+ assert(lock2.owns_lock() == true);
+ assert(lock2.mutex() == &mon1);
+}
+
+void monitor_lock_move_tests()
+{
+ std::cerr << __FUNCTION__ << "... ";
+ {
+ typedef poet::monitor_ptr<int> monitor_type;
+ monitor_type mon(new int(0));
+ monitor_lock_move_test<poet::monitor_unique_lock<monitor_type>, poet::monitor_unique_lock<monitor_type> >(mon);
+ }
+ {
+ typedef poet::monitor_ptr<int, boost::shared_mutex> monitor_type;
+ monitor_type mon(new int(0));
+ monitor_lock_move_test<poet::monitor_upgrade_lock<monitor_type>, poet::monitor_unique_lock<monitor_type> >(mon);
+ // moves into upgrade_lock
+ monitor_lock_move_test<poet::monitor_unique_lock<monitor_type>, poet::monitor_upgrade_lock<monitor_type> >(mon);
+ monitor_lock_move_test<poet::monitor_upgrade_lock<monitor_type>, poet::monitor_upgrade_lock<monitor_type> >(mon);
+ // moves into shared_lock
+ monitor_lock_move_test<poet::monitor_unique_lock<monitor_type>, poet::monitor_shared_lock<monitor_type> >(mon);
+ monitor_lock_move_test<poet::monitor_upgrade_lock<monitor_type>, poet::monitor_shared_lock<monitor_type> >(mon);
+ monitor_lock_move_test<poet::monitor_shared_lock<monitor_type>, poet::monitor_shared_lock<monitor_type> >(mon);
+ // moves from temporary
+ monitor_temp_lock_move_test<poet::monitor_unique_lock<monitor_type> >(mon);
+ monitor_temp_lock_move_test<poet::monitor_upgrade_lock<monitor_type> >(mon);
+ monitor_temp_lock_move_test<poet::monitor_shared_lock<monitor_type> >(mon);
+ }
+ {
+ monitor_swap_test<poet::monitor_unique_lock<poet::monitor<int> >, poet::monitor<int> >();
+ monitor_swap_test<poet::monitor_upgrade_lock<poet::monitor<int, boost::shared_mutex> >, poet::monitor<int, boost::shared_mutex> >();
+ monitor_swap_test<poet::monitor_shared_lock<poet::monitor<int, boost::shared_mutex> >, poet::monitor<int, boost::shared_mutex> >();
+ }
+ upgrade_to_unique_move_test();
+ double_move_test();
+ std::cerr << "OK" << std::endl;
+}
+
+void lock_release_test()
+{
+ typedef poet::monitor_ptr<int> monitor_type;
+ monitor_type mon(new int(0));
+ poet::monitor_unique_lock<monitor_type> lock(mon);
+ assert(lock.owns_lock() == true);
+ assert(lock.mutex() == &mon);
+ monitor_type *result = lock.release();
+ assert(result == &mon);
+ assert(lock.owns_lock() == false);
+ assert(lock.mutex() == 0);
+ poet::monitor_unique_lock<monitor_type> lock2(mon, boost::adopt_lock_t());
+ assert(lock2.owns_lock() == true);
+ assert(lock2.mutex() == &mon);
+ poet::monitor_unique_lock<monitor_type> lock3(mon, boost::defer_lock_t());
+ assert(lock3.try_lock() == false);
+}
+
+class waiting_class: public poet::monitor_base
+{
+public:
+ waiting_class(): _notified(false), _waiting(false)
+ {}
+ void do_wait()
+ {
+ while(_notified == false)
+ {
+ _waiting = true;
+ wait();
+ _waiting = false;
+ }
+ }
+ void do_notify()
+ {
+ _notified = true;
+ notify_all();
+ }
+ bool waiting() const {return _waiting;}
+private:
+ bool _notified;
+ bool _waiting;
+};
+
+typedef poet::monitor_ptr<waiting_class, poet::acyclic_mutex<boost::mutex> > acyclic_monitor_type;
+
+void acyclic_monitor_thread_func(acyclic_monitor_type mon)
+{
+ mon->do_wait();
+}
+
+void acyclic_monitor_test()
+{
+ /* new boost.thread implementation should allow non-boost.thread mutexes to
+ be used with conditions .*/
+ acyclic_monitor_type mon(new waiting_class);
+ boost::thread mythread(boost::bind(&acyclic_monitor_thread_func, mon));
+ while(mon->waiting() == false) boost::this_thread::sleep(boost::posix_time::millisec(10));
+ mon->do_notify();
+ mythread.join();
+}
+
+int main(int argc, const char **argv)
+{
+ monitor_unique_lock_test();
+ monitor_rw_lock_test();
+ lockable_concept_test();
+ monitor_lock_move_tests();
+ lock_release_test();
+ acyclic_monitor_test();
+
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/not_default_constructible_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/not_default_constructible_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,26 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <poet/future.hpp>
+#include <iostream>
+
+class not_def_con
+{
+public:
+ not_def_con(int)
+ {}
+ not_def_con(const not_def_con&)
+ {}
+};
+
+int main()
+{
+ poet::promise<not_def_con> prom;
+ poet::future<not_def_con> fut(prom);
+ BOOST_ASSERT(fut.ready() == false);
+ prom.fulfill(not_def_con(0));
+ BOOST_ASSERT(fut.ready());
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/promise_count_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/promise_count_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,76 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/assert.hpp>
+#include <boost/optional.hpp>
+#include <iostream>
+#include <poet/future.hpp>
+
+void future_count_test()
+{
+ poet::promise<double> mypromise;
+ BOOST_ASSERT(mypromise.has_future() == false);
+
+ boost::optional<poet::future<double> > fut0(mypromise);
+ BOOST_ASSERT(mypromise.has_future());
+
+ {
+ poet::future<int> fut1 = fut0.get();
+ BOOST_ASSERT(mypromise.has_future());
+
+ fut0.reset();
+ BOOST_ASSERT(mypromise.has_future());
+ }
+
+ BOOST_ASSERT(mypromise.has_future() == false);
+}
+
+void promise_void_future_count_test()
+{
+ poet::promise<double> mypromise;
+ poet::promise<void> void_promise = mypromise;
+ BOOST_ASSERT(void_promise.has_future() == false);
+
+ boost::optional<poet::future<double> > fut0(mypromise);
+ BOOST_ASSERT(void_promise.has_future());
+
+ fut0.reset();
+
+ BOOST_ASSERT(void_promise.has_future() == false);
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+ poet::future<double> myfuture;
+ {
+ poet::promise<double> mypromise_copy;
+ {
+ poet::promise<double> mypromise;
+ myfuture = poet::future<double>(mypromise);
+ BOOST_ASSERT(myfuture.has_exception() == false);
+ mypromise_copy = mypromise;
+ }
+ BOOST_ASSERT(myfuture.has_exception() == false);
+ }
+ BOOST_ASSERT(myfuture.has_exception() == true);
+ try
+ {
+ myfuture.get();
+ BOOST_ASSERT(false);
+ }
+ catch(const poet::uncertain_future &)
+ {}
+ catch(...)
+ {
+ BOOST_ASSERT(false);
+ }
+
+ future_count_test();
+ promise_void_future_count_test();
+
+ std::cerr << "OK\n";
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/timed_join_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/timed_join_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,30 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/bind.hpp>
+#include <boost/thread.hpp>
+#include <poet/active_function.hpp>
+#include <iostream>
+#include <vector>
+
+static int delayed_value()
+{
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ return 1;
+};
+
+int main()
+{
+ poet::active_function<int ()> async_call(&delayed_value);
+ poet::future<int> fut = async_call();
+ boost::system_time timeout = boost::get_system_time() + boost::posix_time::millisec(500);
+ bool result = fut.timed_join(timeout);
+ BOOST_ASSERT(result == false);
+ timeout = timeout + boost::posix_time::seconds(1);
+ result = fut.timed_join(timeout);
+ BOOST_ASSERT(result == true);
+ std::cout << "Test passed." << std::endl;
+ return 0;
+}
Added: sandbox/libpoet/trunk/test/undead_active_function_test.cpp
==============================================================================
--- (empty file)
+++ sandbox/libpoet/trunk/test/undead_active_function_test.cpp 2011-03-18 16:01:26 EDT (Fri, 18 Mar 2011)
@@ -0,0 +1,38 @@
+// Copyright (C) Frank Mori Hess 2007
+// 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 <boost/assert.hpp>
+#include <boost/thread.hpp>
+#include <iostream>
+#include <poet/active_function.hpp>
+#include <vector>
+
+int passive_function()
+{
+ std::cerr << __FUNCTION__ << ": going to sleep." << std::endl;
+ boost::this_thread::sleep(boost::posix_time::seconds(1));
+ std::cerr << __FUNCTION__ << ": returning result." << std::endl;
+ return 1;
+}
+
+int main()
+{
+ std::cerr << __FILE__ << "... ";
+
+ std::vector<poet::future<int> > results;
+ {
+ poet::active_function<int ()> short_lived(&passive_function);
+ results.push_back(short_lived());
+ results.push_back(short_lived());
+ }
+ std::cerr << "active function has been destroyed." << std::endl;
+ unsigned i;
+ for(i = 0; i < results.size(); ++i)
+ {
+ results.at(i).get();
+ }
+ std::cerr << "OK" << std::endl;
+ return 0;
+}
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk