WORK IN PROGRESS ================ This directory contains an experimental implementation of SVN++, a high-level Subversion C++ API. It is far from complete and may never see the light of day. On the other hand, one good reason for having a high-level C++ API is to use it as a baseline for Swig-generated bindings. Our current set of Perl, Python and Ruby bindings is too heterogeneous in terms of feature set, object and usage model. They're almost as hard to use as the C API itself. DESIGN GOALS ============ In no particular order: * Use modern C++ constructs (the current baseline is C++11). * Hide the dependency on APR that is exposed in Subversion's C API. * Use separate C++ types for different kinds of values returned from the C API (e.g., dirent vs. property value vs. URL), to make it easier to create generic typemaps for Swig. * Provide both synchronous and asynchronous interfaces. * Avoid unnecessary copies by defining strict lifetimes for returned values. * Provide API variants that accept wide strings as well as UTF-8-encoded narrow strings. * Provide high-level constructs for common parameter types; e.g., revision ranges and lists for diff, merge, etc. * Provide optional header-only conversions and overload for Boost types (e.g., boost::tribool, boost::filesystem::path), which can be enabled by users by defining the SVNXX_USE_BOOST symbol. These convenience overloads and conversions must *not* make the SVN++ library depend on any Boost runtime libraries. * API versioning (how?). API COVERAGE ============ Planned: * libsvn_client (highest priority) * svn_mtcc_* * utilities (diff, revision ranges/lists, etc.) * libsvn_ra * libsvn_repos/libsvn_fs (lowest priority) Not planned: * libsvn_subr * libsvn_wc C++ NAMESPACES AND SOURCE LAYOUT ================================ Public API ---------- The public API is in namespace apache::subversion::svnxx and we define a namespace alias for that: namespace svn = ::apache::subversion::svnxx All elements of the public API are defined or declared in header files in the directory .../include/svnxx/*.hpp with the single header file .../include/svnxx.hpp importing all relevant headers from that directory. Implementation details used by the public API and visible to user code but that should not be directly used by user code are in the namespace apache::subversion::svnxx::detail and should be defined in header files in the directory: .../include/svnxx/detail/*.hpp Note on API versioning ---------------------- Version-specific elements of the public API should be defined in namespaces within the public namespace; e.g., for version 1.13: apache::subversion::svnxx::v_1_13 and the default (or selected) version will be exposed in the parent namespace by inlining the namespace declaration. This versioning does not apply to things declared in svn::detail. Implementation -------------- All entities that are private to the implementation should be in the namespace apache::subversion::svnxx::impl and defined in header files within the source directory tree: .../src/private/*_private.hpp with the single header file .../src/private.hpp importing all relevant headers from that directory. The exception to this rule are C++ wrappers for APR types, which are defined in the namespace apache::subversion::svnxx::apr in header files in the directory: .../src/aprwrap/*.hpp with the single header file .../src/aprwrap.hpp importing all relevant headers from that directory. ==================================================================== IMPLEMENTATION NOTES ==================== Asynchronous Operations (TODO) ------------------------------ In the current model of asyncrhonous operations, we do not protect against using the same svn_client_ctx_t object from multiple threads. This _should_ be safe as long as the callback implementations are aware of it, but we should consider changing the design so that whilst svn::client::context can be shared, we create the actual svn_client_ctx_t on the fly for each operation -- similarly to how we create a the scratch pool.