From 9f384144ed2c421fff2c698e68710557dda6be1f Mon Sep 17 00:00:00 2001
From: Ramin Yaghoubzadeh <ryaghoubzadeh@uni-bielefeld.de>
Date: Fri, 27 Mar 2015 18:42:54 +0100
Subject: [PATCH] C++: Initial basic documentation of all relevant classes.

Also changed constructors of PayloadEntryProxy to protected.
---
 ipaacalib/cpp/include/ipaaca/ipaaca-buffers.h |  71 +++++++-
 ipaacalib/cpp/include/ipaaca/ipaaca-ius.h     |  53 ++++++
 ipaacalib/cpp/include/ipaaca/ipaaca-payload.h | 158 +++++++++++-------
 ipaacalib/cpp/include/ipaaca/ipaaca.h         |   3 +-
 ipaacalib/cpp/src/ipaaca-buffers.cc           |  11 ++
 5 files changed, 228 insertions(+), 68 deletions(-)

diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-buffers.h b/ipaacalib/cpp/include/ipaaca/ipaaca-buffers.h
index 806ff3c..2b57075 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-buffers.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-buffers.h
@@ -69,6 +69,7 @@ IPAACA_HEADER_EXPORT class SmartLinkMap {//{{{
 		IPAACA_HEADER_EXPORT void _replace_links(const LinkMap& links);
 };//}}}
 
+/// The empty link set is returned if undefined links are read for an IU.
 IPAACA_MEMBER_VAR_EXPORT const LinkSet EMPTY_LINK_SET;
 
 /// Configuration object that can be passed to Buffer constructors.
@@ -113,11 +114,20 @@ IPAACA_HEADER_EXPORT class BufferConfigurationBuilder: private BufferConfigurati
 
 };//}}}
 
-/// Type of user-space functions that can be registered on a Buffer to receive IU events.
+/** \brief Type of user-space functions that can be registered on a Buffer to receive IU events.
+ *
+ * The signature of these functions is void(shared_ptr<IUInterface> iu, IUEventType evt_type, bool local), where:<br/>
+ *     iu can be used mostly like a locally-generated IU reference (e.g. iu->payload() ...)<br/>
+ *     evt_type is one of IU_ADDED, IU_UPDATED, IU_RETRACTED, IU_DELETED, IU_LINKSUPDATED, IU_COMMITTED, IU_MESSAGE<br/>
+ *     local indicates that a remote change to a local IU (in an OutputBuffer) was effected
+ *
+ *
+ */
 IPAACA_HEADER_EXPORT typedef boost::function<void (boost::shared_ptr<IUInterface>, IUEventType, bool)> IUEventHandlerFunction;
 
-/// Internal handler type (wraps used-specified IUEventHandlerFunction)
-IPAACA_LOG_LEVEL_NONE, IPAACA_HEADER_EXPORT class IUEventHandler {//{{{
+/** \brief Internal handler type used in Buffer (wraps used-specified IUEventHandlerFunction)
+ */
+IPAACA_HEADER_EXPORT class IUEventHandler {//{{{
 	protected:
 		IPAACA_MEMBER_VAR_EXPORT IUEventHandlerFunction _function;
 		IPAACA_MEMBER_VAR_EXPORT IUEventType _event_mask;
@@ -137,9 +147,9 @@ IPAACA_LOG_LEVEL_NONE, IPAACA_HEADER_EXPORT class IUEventHandler {//{{{
 };//}}}
 
 /**
- * \brief Buffer base class
+ * \brief Buffer base class. Derived classes use its handler registration functionality.
  *
- * This class is never instantiated directly (use OutputBuffer and InputBuffer, respectively).
+ * \b Note: This class is never instantiated directly (use OutputBuffer and InputBuffer, respectively).
  */
 IPAACA_HEADER_EXPORT class Buffer { //: public boost::enable_shared_from_this<Buffer> {//{{{
 	friend class IU;
@@ -173,7 +183,42 @@ IPAACA_HEADER_EXPORT class Buffer { //: public boost::enable_shared_from_this<Bu
 	public:
 		IPAACA_HEADER_EXPORT virtual inline ~Buffer() { }
 		IPAACA_HEADER_EXPORT inline const std::string& unique_name() { return _unique_name; }
+		/// This version of register_handler takes a set of several category interests instead of just one.
 		IPAACA_HEADER_EXPORT void register_handler(IUEventHandlerFunction function, IUEventType event_mask, const std::set<std::string>& categories);
+		/** \brief Register a user-specified handler for IU events.
+		 *
+		 * \param function A function [object] that can be converted to #IUEventHandlerFunction (examples below)
+		 * \param event_mask Which event types to relay to the user (default: all)
+		 * \param category The category to filter for (default: do not filter)
+		 *
+		 * \b Examples:
+		 *
+		 * Adding a plain function as a handler:<br/>
+		 *     <pre>
+		 *     void global_iu_handler(IUInterface::ptr iu, IUEventType type, bool local) { ... }
+		 *     ...
+		 *     int main() {
+		 *         OutputBuffer::ptr outbuf = OutputBuffer::create("mybufname");
+		 *         outbuf->register_handler(global_iu_handler);
+		 *         ...
+		 *     }
+		 *     </pre>
+		 *
+		 * Adding a class member as a handler (using boost::bind):<br/>
+		 *     <pre>
+		 *     class MyClass {
+		 *         protected:
+		 *             void my_internal_iu_handler(IUInterface::ptr iu, IUEventType type, bool local) { ... }
+		 *             InputBuffer::ptr inbuf;
+		 *         public:
+		 *             MyClass() {
+		 *                 inbuf = InputBuffer::create("bufname", "categoryInterest");
+		 *                 inbuf->register_handler(boost::bind(&MyClass::my_internal_iu_handler, this, _1, _2, _3));
+		 *             }
+		 *     };
+		 *     </pre>
+		 *
+		 */
 		IPAACA_HEADER_EXPORT void register_handler(IUEventHandlerFunction function, IUEventType event_mask = IU_ALL_EVENTS, const std::string& category="");
 		//_IPAACA_ABSTRACT_ virtual void add(boost::shared_ptr<IUInterface> iu) = 0;
 		IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual boost::shared_ptr<IUInterface> get(const std::string& iu_uid) = 0;
@@ -225,6 +270,7 @@ IPAACA_HEADER_EXPORT class OutputBuffer: public Buffer { //, public boost::enabl
 
 		IPAACA_HEADER_EXPORT void _retract_iu(boost::shared_ptr<IU> iu);
 	protected:
+		/// \b Note: constructor is protected. Use create()
 		IPAACA_HEADER_EXPORT OutputBuffer(const std::string& basename, const std::string& channel=""); // empty string auto-replaced with __ipaaca_static_option_default_channel
 		IPAACA_HEADER_EXPORT void _initialize_server();
 	public:
@@ -287,6 +333,7 @@ IPAACA_HEADER_EXPORT class InputBuffer: public Buffer { //, public boost::enable
 			IPAACA_WARNING("(ERROR) InputBuffer::_send_iu_resendrequest() should never be invoked")
 		}*/
 	protected:
+		/// \b Note: all constructors are protected. Use create()
 		IPAACA_HEADER_EXPORT InputBuffer(const BufferConfiguration& bufferconfiguration);
 		IPAACA_HEADER_EXPORT InputBuffer(const std::string& basename, const std::set<std::string>& category_interests);
 		IPAACA_HEADER_EXPORT InputBuffer(const std::string& basename, const std::vector<std::string>& category_interests);
@@ -298,15 +345,27 @@ IPAACA_HEADER_EXPORT class InputBuffer: public Buffer { //, public boost::enable
 		IPAACA_MEMBER_VAR_EXPORT bool triggerResend;
 
 	public:
-		/// Specify whether old, but previously unknown, IUs should be requested to be sent to the buffer over a hidden channel.
+		/// Specify whether old but previously unseen IUs should be requested to be sent to the buffer over a hidden channel.
 		IPAACA_HEADER_EXPORT void set_resend(bool resendActive);
 		IPAACA_HEADER_EXPORT bool get_resend();
+		/// Create InputBuffer according to configuration in BufferConfiguration object
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const BufferConfiguration& bufferconfiguration);
+		/// Create InputBuffer from name and set of category interests
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::set<std::string>& category_interests);
+		/// Create InputBuffer from name and vector of category interests
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::vector<std::string>& category_interests);
+		// /// Create InputBuffer from name and initializer_list of category interests
+		// IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::initializer_list<std::string>& category_interests);
+		/// Convenience function: create InputBuffer from name and one category interest
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1);
+		/// Convenience function: create InputBuffer from name and two category interests [DEPRECATED]
+		[[deprecated("Use create(string, set<string>) instead")]]
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1, const std::string& category_interest2);
+		/// Convenience function: create InputBuffer from name and three category interests [DEPRECATED]
+		[[deprecated("Use create(string, set<string>) instead")]]
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1, const std::string& category_interest2, const std::string& category_interest3);
+		/// Convenience function: create InputBuffer from name and four category interests [DEPRECATED]
+		[[deprecated("Use create(string, set<string>) instead")]]
 		IPAACA_HEADER_EXPORT static boost::shared_ptr<InputBuffer> create(const std::string& basename, const std::string& category_interest1, const std::string& category_interest2, const std::string& category_interest3, const std::string& category_interest4);
 		IPAACA_HEADER_EXPORT ~InputBuffer() {
 			IPAACA_IMPLEMENT_ME
diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h b/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h
index 73d9648..f4fc8fc 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-ius.h
@@ -50,6 +50,14 @@
 #endif
 
 
+/** \brief Abstract base class for all IU-type classes
+ *
+ * In user programs, classes IU or Message should be instantiated.
+ *
+ * This abstract type is used in handler callback functions and
+ * contains most generic user-space functions.
+ *
+ */
 IPAACA_HEADER_EXPORT class IUInterface {//{{{
 	friend class IUConverter;
 	friend class MessageConverter;
@@ -87,38 +95,68 @@ IPAACA_HEADER_EXPORT class IUInterface {//{{{
 		IPAACA_HEADER_EXPORT void _add_and_remove_links(const LinkMap& add, const LinkMap& remove) { _links._add_and_remove_links(add, remove); }
 		IPAACA_HEADER_EXPORT void _replace_links(const LinkMap& links) { _links._replace_links(links); }
 	public:
+		/// Return whether IU has already been published (is in a Buffer).
 		IPAACA_HEADER_EXPORT inline bool is_published() { return (_buffer != 0); }
+		/// Return auto-generated UID string (set during IU construction)
 		IPAACA_HEADER_EXPORT inline const std::string& uid() const { return _uid; }
+		/// Return current IU revision number (incremented for each update)
 		IPAACA_HEADER_EXPORT inline revision_t revision() const { return _revision; }
+		/// Return the IU category string (set during IU construction)
 		IPAACA_HEADER_EXPORT inline const std::string& category() const { return _category; }
+		/// Return the channel name the IU is resident on (set on publication)
 		IPAACA_HEADER_EXPORT const std::string& channel();
+		/// Return the payload type (default "JSON")
 		IPAACA_HEADER_EXPORT inline const std::string& payload_type() const { return _payload_type; }
+		/// Return the owner name (unique fully-qualified buffer name, set on publication)
 		IPAACA_HEADER_EXPORT inline const std::string& owner_name() const { return _owner_name; }
+		/// Return whether IU has been committed to (i.e. is complete, confirmed, and henceforth constant)
 		IPAACA_HEADER_EXPORT inline bool committed() const { return _committed; }
+		/// Return the access mode (not relevant for the time being)
 		IPAACA_HEADER_EXPORT inline IUAccessMode access_mode() const { return _access_mode; }
+		/// Return whether IU is read only (committed, a Message, or explicitly set read-only by owner)
 		IPAACA_HEADER_EXPORT inline bool read_only() const { return _read_only; }
 		//inline boost::shared_ptr<Buffer> buffer() { return _buffer; }
+		/// Return owning buffer [CAVEAT: do not rely on this function for future code]
 		IPAACA_HEADER_EXPORT inline Buffer* buffer() const { return _buffer; }
+		/// Return the link set for an arbitrary link type (e.g. "grounded_in"), or EMPTY_LINK_SET
 		IPAACA_HEADER_EXPORT inline const LinkSet& get_links(std::string type) { return _links.get_links(type); }
+		/// Return the map of all defined links
 		IPAACA_HEADER_EXPORT inline const LinkMap& get_all_links() { return _links.get_all_links(); }
 		// Payload
+		/// Return the Payload object of this IU, overridden in the derived classes
 		IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual Payload& payload() = 0;
+		/// Const version of payload()
 		IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual const Payload& const_payload() const = 0;
 		// setters
+		/// Commit to an IU (only possible for the IU owner)
 		IPAACA_HEADER_EXPORT _IPAACA_ABSTRACT_ virtual void commit() = 0;
 		// functions to modify and update links:
 		//IPAACA_HEADER_EXPORT void _publish_resend(boost::shared_ptr<IU> iu, const std::string& hidden_scope_name);
 
+		/// Add a set of new UIDs for a specific link type
 		IPAACA_HEADER_EXPORT void add_links(const std::string& type, const LinkSet& targets, const std::string& writer_name = "");
+		/// Remove a set of UIDs from a link type
 		IPAACA_HEADER_EXPORT void remove_links(const std::string& type, const LinkSet& targets, const std::string& writer_name = "");
+		/// Bulk link modification function
 		IPAACA_HEADER_EXPORT void modify_links(const LinkMap& add, const LinkMap& remove, const std::string& writer_name = "");
+		/// Bulk link override function
 		IPAACA_HEADER_EXPORT void set_links(const LinkMap& links, const std::string& writer_name = "");
 		//    (with cpp specific convenience functions:)
+		/// Convenience function (C++): add a single UID string to an arbitrary link set
 		IPAACA_HEADER_EXPORT void add_link(const std::string& type, const std::string& target, const std::string& writer_name = "");
+		/// Convenience function (C++): remove a single UID string from an arbitrary link set (if contained)
 		IPAACA_HEADER_EXPORT void remove_link(const std::string& type, const std::string& target, const std::string& writer_name = "");
 	typedef boost::shared_ptr<IUInterface> ptr;
 };//}}}
 
+/** \brief Class of locally-owned IU objects.
+ *
+ * Use IU::create() (static) to create references to new IUs.
+ * Use IU::payload() to access the IUs payload object.
+ * Use OutputBuffer::add() to publish IUs.
+ *
+ * See IUInterface for a generic description of most user-space member functions.
+ */
 IPAACA_HEADER_EXPORT class IU: public IUInterface {//{{{
 	friend class Buffer;
 	friend class InputBuffer;
@@ -155,6 +193,18 @@ IPAACA_HEADER_EXPORT class IU: public IUInterface {//{{{
 	public:
 	typedef boost::shared_ptr<IU> ptr;
 };//}}}
+/** \brief Class of locally-owned message objects ('one-shot' IUs).
+ *
+ * This class works the same as IU, except that it sets the internal
+ * flags so that it is received as a message (ephemeral object) on
+ * the remote sides, instead of a persistent objects.
+ *
+ * Likewise, it is not actually stored by OutputBuffer::add(), but just broadcast.
+ * 
+ * See IUInterface for a generic description of most user-space member functions.
+ *
+ * \see IU, IUInterface
+ */
 IPAACA_HEADER_EXPORT class Message: public IU {//{{{
 	friend class Buffer;
 	friend class InputBuffer;
@@ -181,6 +231,7 @@ IPAACA_HEADER_EXPORT class Message: public IU {//{{{
 	typedef boost::shared_ptr<Message> ptr;
 };//}}}
 
+/// Copy of a remote IU, received in an InputBuffer. Setter functions call RPC over the backend (RSB). \b Note: Typically handled only as reference in a handler in user space.
 IPAACA_HEADER_EXPORT class RemotePushIU: public IUInterface {//{{{
 	friend class Buffer;
 	friend class InputBuffer;
@@ -209,6 +260,7 @@ IPAACA_HEADER_EXPORT class RemotePushIU: public IUInterface {//{{{
 		IPAACA_HEADER_EXPORT void _apply_retraction();
 	typedef boost::shared_ptr<RemotePushIU> ptr;
 };//}}}
+/// Copy of a remote Message, received in an InputBuffer. Setter functions all fail.\b Note: Typically handled only as reference in a handler in user space.
 IPAACA_HEADER_EXPORT class RemoteMessage: public IUInterface {//{{{
 	friend class Buffer;
 	friend class InputBuffer;
@@ -238,6 +290,7 @@ IPAACA_HEADER_EXPORT class RemoteMessage: public IUInterface {//{{{
 	typedef boost::shared_ptr<RemoteMessage> ptr;
 };//}}}
 
+/// Mock IU for testing purposes. [INTERNAL]
 IPAACA_HEADER_EXPORT class FakeIU: public IUInterface {//{{{
 	friend class Buffer;
 	friend class InputBuffer;
diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
index 482d137..6d8e863 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca-payload.h
@@ -52,6 +52,7 @@
 #endif
 
 // casting operators from Value&
+/// 'Smart' type conversions, allowing for some leeway type-wise (e.g. string "1.3" can be successfully cast to double or long). Used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT template<typename T> T json_value_cast(const rapidjson::Value&);
 IPAACA_HEADER_EXPORT template<typename T> T json_value_cast(const rapidjson::Value* value) { if (!value) return T(); return json_value_cast<T>(*value); }
 IPAACA_HEADER_EXPORT template<> long json_value_cast(const rapidjson::Value&);
@@ -65,14 +66,20 @@ IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> json_value_ca
 
 // helpers to set Value& from various standard types
 //IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, T t);
+/// Setter to store int into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, int);
+/// Setter to store int into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, long);
+/// Setter to store long into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, double);
+/// Setter to store double into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, bool);
+/// Setter to store bool into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const std::string&);
+/// Setter to store std::string into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT void pack_into_json_value(rapidjson::Value&, rapidjson::Document::AllocatorType&, const char*);
 // helpers to set Value& from several standard containers containing the above standard types
-/// set Value& from vector<T>
+/// Setter to store a vector of supported basic types into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::vector<T>& ts)
 {
 	valueobject.SetArray();
@@ -82,7 +89,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V
 		valueobject.PushBack(newv, allocator);
 	}
 }
-/// set Value& from list<T>
+/// Setter to store a list of supported basic types into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::list<T>& ts)
 {
 	valueobject.SetArray();
@@ -92,7 +99,7 @@ IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::V
 		valueobject.PushBack(newv, allocator);
 	}
 }
-/// set Value& from map<string, T>
+/// Setter to store a map of string -> supported basic types into json value, used by PayloadEntryProxy.
 IPAACA_HEADER_EXPORT template<typename T> void pack_into_json_value(rapidjson::Value& valueobject, rapidjson::Document::AllocatorType& allocator, const std::map<std::string, T>& ts)
 {
 	valueobject.SetObject();
@@ -110,6 +117,8 @@ IPAACA_HEADER_EXPORT template<> void pack_into_json_value(rapidjson::Value&, rap
 */
 
 // FIXME TODO locking / invalidating proxy on first write of a payload entry
+
+/// Single payload entry wrapping a rapidjson::Document with some conversion glue. Also handles copy-on-write Document cloning.
 IPAACA_HEADER_EXPORT class PayloadDocumentEntry//{{{
 {
 	friend std::ostream& operator<<(std::ostream& os, std::shared_ptr<PayloadDocumentEntry> entry);
@@ -132,57 +141,12 @@ IPAACA_HEADER_EXPORT class PayloadDocumentEntry//{{{
 };
 //}}}
 
-/*
-IPAACA_HEADER_EXPORT class LegacyStringPayloadEntryProxy//{{{
-{
-	protected:
-		IPAACA_MEMBER_VAR_EXPORT Payload* _payload;
-		IPAACA_MEMBER_VAR_EXPORT std::string _key;
-	public:
-		IPAACA_HEADER_EXPORT PayloadEntryProxy(Payload* payload, const std::string& key);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const std::string& value);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const char* value);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(double value);
-		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(bool value);
-		IPAACA_HEADER_EXPORT operator std::string();
-		IPAACA_HEADER_EXPORT operator long();
-		IPAACA_HEADER_EXPORT operator double();
-		IPAACA_HEADER_EXPORT operator bool();
-		IPAACA_HEADER_EXPORT std::string to_str();
-		//long to_int() { return operator long(); ;
-		IPAACA_HEADER_EXPORT long to_long();
-		IPAACA_HEADER_EXPORT double to_float();
-		IPAACA_HEADER_EXPORT bool to_bool();
-		// getters
-		IPAACA_HEADER_EXPORT template<typename T> T get(); // specializations below
-		// setters
-};
-// Available interpretations of payload entries (or children thereof) below.
-//  Usage of standard complex data structures (vector etc.) currently entails
-//  casting all entries to a uniform type (a-priori choice: std::string).
-IPAACA_HEADER_EXPORT template<> long PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> double PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> bool PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::string PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::vector<std::string> PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::list<std::string> PayloadEntryProxy::get();
-IPAACA_HEADER_EXPORT template<> std::map<std::string, std::string> PayloadEntryProxy::get();
-
-//}}}
-*/
-
 typedef std::map<std::string, PayloadDocumentEntry::ptr> PayloadDocumentStore;
 
-/*
-IPAACA_HEADER_EXPORT class PayloadDocumentStore//{{{
-: public std::map<std::string, PayloadDocumentEntry::ptr>
-{
-	public:
-	typedef std::shared_ptr<PayloadDocumentStore> ptr;
-};
-//}}}
-*/
-
+/** \brief Central class containing the user-set payload of any IUInterface class (IU, Message, RemotePushIU or RemoteMessage)
+ *
+ * Obtained by calling payload() on any IUInterface derived object. Created during IU creation.
+ */
 IPAACA_HEADER_EXPORT class Payload//{{{
 {
 	friend std::ostream& operator<<(std::ostream& os, const Payload& obj);
@@ -217,20 +181,26 @@ IPAACA_HEADER_EXPORT class Payload//{{{
 	public:
 		IPAACA_HEADER_EXPORT inline const std::string& owner_name() { return _owner_name; }
 		// access
+		/// Obtain a payload item by name as a PayloadEntryProxy (returning null-type proxy if undefined)
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const std::string& key);
+		/// Legacy / convenience function: interpret the payload map as a map string->string (casting all entries to string)
 		IPAACA_HEADER_EXPORT operator std::map<std::string, std::string>();
+		/// set or overwrite a single payload entry with a PayloadDocumentEntry object (typically \b not called by users - use PayloadEntryProxy::operator=() instead).
 		IPAACA_HEADER_EXPORT inline void set(const std::string& k, PayloadDocumentEntry::ptr entry) { _internal_set(k, entry); }
+		/// remove a single payload entry
 		IPAACA_HEADER_EXPORT inline void remove(const std::string& k) { _internal_remove(k); }
 		// FIXME: json: these two must support a bunch of standard types, not [only] json (users touch them)
 		//  to be more precise: types of map<string, T> with T several interesting things (string, list<string>, etc.)
 		//IPAACA_HEADER_EXPORT inline void set(const std::map<std::string, const rapidjson::Document&>& all_elems) { _internal_replace_all(all_elems); }
 		//IPAACA_HEADER_EXPORT inline void merge(const std::map<std::string, const rapidjson::Document&>& elems_to_merge) { _internal_merge(elems_to_merge); }
 		// legacy / convenience setter
+		/// Legacy / convenience function: set the whole payload map from a map string->string (all JSON types are also set as string, no interpretation)
 		IPAACA_HEADER_EXPORT void set(const std::map<std::string, std::string>& all_elems);
 	protected:
 		IPAACA_HEADER_EXPORT PayloadDocumentEntry::ptr get_entry(const std::string& k); // json, changed str to proxy here, too
 	public:
 		[[deprecated("Use operator[] and operator std::string() instead")]]
+		/// Read a single entry as string [DEPRECATED] (use string conversion in PayloadEntryProxy instead)
 		IPAACA_HEADER_EXPORT std::string get(const std::string& k); // DEPRECATED
 	protected:
 		IPAACA_MEMBER_VAR_EXPORT unsigned long internal_revision;
@@ -238,11 +208,24 @@ IPAACA_HEADER_EXPORT class Payload//{{{
 	public:
 		IPAACA_HEADER_EXPORT inline bool revision_changed(unsigned long reference_revision) { return internal_revision != reference_revision; }
 	public:
+		/// obtain a standard iterator marking the first entry in the payload
 		IPAACA_HEADER_EXPORT PayloadIterator begin();
+		/// obtain a standard iterator past the last entry in the payload
 		IPAACA_HEADER_EXPORT PayloadIterator end();
 	typedef boost::shared_ptr<Payload> ptr;
 };//}}}
 
+/** \brief Standard iterator for Payload (example below)
+ *
+ * \b Examples:
+ * <pre>
+ * // Print all key-value pairs from a payload (C++11)
+ * for (auto kv_pair: myiu->payload()) {
+ *     std::cout << kv_pair.first << " -> " << (std::string) kv_pair.second << std::endl;
+ * }
+ * </pre>
+ *
+ */
 IPAACA_HEADER_EXPORT class PayloadIterator//{{{
 {
 	friend class Payload;
@@ -265,6 +248,7 @@ IPAACA_HEADER_EXPORT class PayloadIterator//{{{
 };
 //}}}
 
+/// Iterator over a payload entry that is a json map-type object (returned type during dereferencing: pair<string, PayloadEntryProxy>)
 IPAACA_HEADER_EXPORT class PayloadEntryProxyMapIterator//{{{
 {
 	public:
@@ -281,6 +265,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyMapIterator//{{{
 		IPAACA_HEADER_EXPORT bool operator!=(const PayloadEntryProxyMapIterator& other_iter);
 };
 //}}}
+/// Iterator over a payload entry that is a json list-type object (returned type during dereferencing: PayloadEntryProxy)
 IPAACA_HEADER_EXPORT class PayloadEntryProxyListIterator//{{{
 {
 	protected:
@@ -296,6 +281,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyListIterator//{{{
 		IPAACA_HEADER_EXPORT bool operator!=(const PayloadEntryProxyListIterator& other_iter);
 };
 //}}}
+/// Interpretation of a variant json value as a map-type object
 IPAACA_HEADER_EXPORT class PayloadEntryProxyMapDecorator//{{{
 {
 	public:
@@ -306,6 +292,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyMapDecorator//{{{
 		IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* proxy;
 };
 //}}}
+/// Interpretation of a variant json value as a list-type object
 IPAACA_HEADER_EXPORT class PayloadEntryProxyListDecorator//{{{
 {
 	public:
@@ -317,13 +304,37 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxyListDecorator//{{{
 };
 //}}}
 
-/** PayloadEntryProxy description */
+/** \brief Reference to an existent or nonexistent payload entry (or a value deeper in the json tree)
+ *
+ * This class is returned by IUInterface::operator[].
+ * The proxy handles automatic type conversions, requests remote changes of payloads, and enables navigation into and iteration over structured json objects.
+ *
+ * \b Examples:
+ *
+ * <code>std::string received_name = iu->payload()["name"];</code>  // implicit conversion using operator string()
+ *
+ * <code>std::vector<double> vd = iu->payload()["double_list"];</code>  // some standard container types also supported
+ * 
+ * <code>auto p = iu->payload()["otherKey"];</code>  // auto type is PayloadEntryProxy (conversion is on-demand)
+ *
+ * <code>iu->payload()["double_list"][0] = 100.0;</code>  // accessing and updating an item in a list
+ *
+ * <code>iu->payload()["name_list"] = std::list<std::string>{"Alpha", "Bravo", "Charlie"};</code>  // set from basic uniform containers
+ *
+ * <code>for (auto val: iu->payload()["my_list"].as_list()) { ... }</code>  // as_list is required to select list-type iteration (value type in iteration remains variant)
+ *
+ * <code>for (auto k_v_map: iu->payload()["my_map"].as_map()) { ... }</code>  // as_map is required to select map-type iteration (value type in iteration is a pair, second part remains variant)
+ */
 IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 {
+	friend class Payload;
+	friend class PayloadIterator;
 	friend std::ostream& operator<<(std::ostream& os, const PayloadEntryProxy& proxy);
 	protected:
 	public:
+		/// Select map-style iteration for this proxy (to select iterator content type). Will throw if not actually map-type. See example in the class description.
 		IPAACA_HEADER_EXPORT PayloadEntryProxyMapDecorator as_map();
+		/// Select list-style iteration for this proxy (to select iterator content type). Will throw if not actually list-type. See example in the class description.
 		IPAACA_HEADER_EXPORT PayloadEntryProxyListDecorator as_list();
 	public:
 		//IPAACA_MEMBER_VAR_EXPORT rapidjson::Document* _json_parent_node;
@@ -333,41 +344,52 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 		//
 		// new json stuff / hierarchical navigation
 		//
-		IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* parent; // parent (up to document root -> then null)
+		IPAACA_MEMBER_VAR_EXPORT PayloadEntryProxy* parent; ///< Parent proxy (up to document root -> then null)
 		IPAACA_MEMBER_VAR_EXPORT PayloadDocumentEntry::ptr document_entry; // contains lock and json Doc
-		IPAACA_MEMBER_VAR_EXPORT bool existent; // whether Value exists already (or blindly navigated)
-		IPAACA_MEMBER_VAR_EXPORT bool addressed_as_array; // whether long or string navigation used
-		IPAACA_MEMBER_VAR_EXPORT long addressed_index;
-		IPAACA_MEMBER_VAR_EXPORT std::string addressed_key;
+		IPAACA_MEMBER_VAR_EXPORT bool existent; ///< Whether Value exists already (or else 'blindly' navigated)
+		IPAACA_MEMBER_VAR_EXPORT bool addressed_as_array; ///< Whether long or string navigation was used
+		IPAACA_MEMBER_VAR_EXPORT long addressed_index; ///< Index that was used in list-style access
+		IPAACA_MEMBER_VAR_EXPORT std::string addressed_key; ///< Key that was used in map-style access
 		/// currently navigated value in json tree (or a new Null value)
-		IPAACA_MEMBER_VAR_EXPORT rapidjson::Value* json_value;
+		IPAACA_MEMBER_VAR_EXPORT rapidjson::Value* json_value; ///< json value that corresponds to the current navigation (or nullptr)
 /*	protected:
 		IPAACA_HEADER_EXPORT void connect_to_existing_parents();
 */
-	public:
+	protected:
 		// constructor to create a new top-most parent proxy (from a payload key)
 		IPAACA_HEADER_EXPORT PayloadEntryProxy(Payload* payload, const std::string& key);
 		// constructors for navigation through objects
 		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, const std::string& addressed_key);
 		IPAACA_HEADER_EXPORT PayloadEntryProxy(PayloadEntryProxy* parent, size_t addressed_index);
 	public:
+		/// Return number of contained items (or 0 for non-container types)
 		IPAACA_HEADER_EXPORT size_t size();
+		/// Return whether value corresponds to json 'null'; also true if value is nonexistent so far (e.g. navigated to new map entry)
 		IPAACA_HEADER_EXPORT bool is_null();
+		/// Return whether value is of string type
 		IPAACA_HEADER_EXPORT bool is_string();
+		/// Return whether value is of a numerical type
 		IPAACA_HEADER_EXPORT bool is_number();
+		/// Return whether value is of list type
 		IPAACA_HEADER_EXPORT bool is_list();
+		/// Return whether value is of map type
 		IPAACA_HEADER_EXPORT bool is_map();
 	public:
+		/// Array-style navigation over json value
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](size_t index); // array-style navigation
+		/// Array-style navigation over json value (added to catch [0])
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](int index); // int is UNFORTUNATELY required to catch
 																	  // [0] (addressing using literal zero)
 																	  // because ambiguity with const char*
 																	  // arises if only [](size_t) is provided.
 																	  // size_t is obviously superior ...
 																	  // TODO: remove if better solution known
+		/// Dict-style navigation over json value
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const std::string& key); // dict-style navigation
+		/// Dict-style navigation over json value
 		IPAACA_HEADER_EXPORT PayloadEntryProxy operator[](const char* key);
-		//                   
+		//
+		/// Set or overwrite some portion of a payload from the point navigated to
 		IPAACA_HEADER_EXPORT template<typename T> PayloadEntryProxy& operator=(T t)
 		{
 			PayloadDocumentEntry::ptr new_entry = document_entry->clone(); // copy-on-write, no lock required
@@ -377,8 +399,11 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 			_payload->set(_key, new_entry);
 			return *this;
 		}
+		/// Value comparison with other proxy contents
 		IPAACA_HEADER_EXPORT inline bool operator==(const PayloadEntryProxy& otherproxy) { return (json_value && otherproxy.json_value && ((*json_value)==*(otherproxy.json_value))); }
+		/// Value comparison with other proxy contents
 		IPAACA_HEADER_EXPORT inline bool operator!=(const PayloadEntryProxy& otherproxy) { return !operator==(otherproxy); }
+		/// Value comparison with supported basic types
 		IPAACA_HEADER_EXPORT template<typename T> bool operator==(T othervalue)
 		{
 			if (!json_value) return false;
@@ -389,14 +414,18 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 				return false;
 			}
 		}
+		/// Value comparison with supported basic types
 		IPAACA_HEADER_EXPORT template<typename T> bool operator!=(T othervalue) { return !operator==(othervalue); }
+		/// Value comparison with char* (required to be explicitly added)
 		IPAACA_HEADER_EXPORT inline bool operator==(const char* othervalue)
 		{
 			if (!json_value) return false;
 			return json_value_cast<std::string>(*json_value) == othervalue;
 		}
+		/// Value comparison with char* (required to be explicitly added)
 		IPAACA_HEADER_EXPORT inline bool operator!=(const char* othervalue) { return !operator==(othervalue); }
 		
+		/// Copy value from below other json node, preserving types
 		IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const PayloadEntryProxy& otherproxy);
 		
 		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(const std::string& value);
@@ -404,10 +433,15 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(double value);
 		//IPAACA_HEADER_EXPORT PayloadEntryProxy& operator=(bool value);
 		
+		/// Conversion to std::string (explicit or implicit)
 		IPAACA_HEADER_EXPORT operator std::string();
+		/// Conversion to long (explicit or implicit)
 		IPAACA_HEADER_EXPORT operator long();
+		/// Conversion to double (explicit or implicit)
 		IPAACA_HEADER_EXPORT operator double();
+		/// Conversion to bool (explicit or implicit)
 		IPAACA_HEADER_EXPORT operator bool();
+		/// Conversion to uniform std::vector of supported basic type
 		IPAACA_HEADER_EXPORT template<typename Inner> operator std::vector<Inner>() {
 			if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
 			std::vector<Inner> result;
@@ -416,6 +450,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 			}
 			return result;
 		}
+		/// Conversion to uniform std::list of supported basic type
 		IPAACA_HEADER_EXPORT template<typename Inner> operator std::list<Inner>() {
 			if ((!json_value) || (!json_value->IsArray())) throw PayloadAddressingError();
 			std::list<Inner> result;
@@ -424,6 +459,7 @@ IPAACA_HEADER_EXPORT class PayloadEntryProxy//{{{
 			}
 			return result;
 		}
+		/// Conversion to uniform std::map of string -> supported basic type
 		IPAACA_HEADER_EXPORT template<typename Inner> operator std::map<std::string, Inner>() {
 			if ((!json_value) || (!json_value->IsObject())) throw PayloadAddressingError();
 			std::map<std::string, Inner> result;
diff --git a/ipaacalib/cpp/include/ipaaca/ipaaca.h b/ipaacalib/cpp/include/ipaaca/ipaaca.h
index 7d6f242..04f62ee 100644
--- a/ipaacalib/cpp/include/ipaaca/ipaaca.h
+++ b/ipaacalib/cpp/include/ipaaca/ipaaca.h
@@ -51,7 +51,7 @@ List of most relevant entry points:
 
 Buffers: InputBuffer, OutputBuffer
 
-IUs: IU, Message
+IUs: IUInterface, IU, Message
 
 IU handling (user-set): #IUEventHandlerFunction
 
@@ -190,6 +190,7 @@ IU payload contents: Payload, PayloadEntryProxy
 #include <list>
 #include <algorithm>
 #include <utility>
+#include <initializer_list>
 
 namespace ipaaca {
 
diff --git a/ipaacalib/cpp/src/ipaaca-buffers.cc b/ipaacalib/cpp/src/ipaaca-buffers.cc
index 99a2b91..6ef4496 100644
--- a/ipaacalib/cpp/src/ipaaca-buffers.cc
+++ b/ipaacalib/cpp/src/ipaaca-buffers.cc
@@ -476,6 +476,17 @@ IPAACA_EXPORT InputBuffer::InputBuffer(const std::string& basename, const std::v
 	_create_category_listener_if_needed(_uuid);
 	triggerResend = false;
 }
+/*IPAACA_EXPORT InputBuffer::InputBuffer(const std::string& basename, const std::initializer_list<std::string>& category_interests)
+:Buffer(basename, "IB")
+{
+	_channel = __ipaaca_static_option_default_channel;
+
+	for (std::initializer_list<std::string>::const_iterator it=category_interests.begin(); it!=category_interests.end(); ++it) {
+		_create_category_listener_if_needed(*it);
+	}
+	_create_category_listener_if_needed(_uuid);
+	triggerResend = false;
+}*/
 IPAACA_EXPORT InputBuffer::InputBuffer(const std::string& basename, const std::string& category_interest1)
 :Buffer(basename, "IB")
 {
-- 
GitLab