On 13 Oct 2014 at 12:16, Antony Polukhin wrote:
Well, I do have a lot of demands on my time these next few months. Currently three new Boost libraries will be appearing from me by March 2015, so I am not volunteering for even more work.
That said, given how trivial the above metaprogrammed Itanium type mangler is, I would be happy to collaborate with someone else on an implementation. You'll just need to be patient with my rate of progress, I only get Saturdays most weeks for non-work work items and that is usually spent on closing Boost.Thread defects or trying to find some time to work on AFIO.
I'd appreciate any help. Task of name mangling does not seem review blocking and can be easily done later at any time.
Here's just an idea how importing could be done in a nice way without aliases if we had a fully functional mangler:
dll::shared_library lib(path_to_lib); typedef boost::variant
vis_t; // mangle_get method has signature of the method and it's full name, // so a Mangler could create a correct mangled name without forward declaration auto f = lib.mangle_get
("foo::adl_barrier:: export_me_function");
I'd be much happier with: auto f = BOOST_DLL_MANGLE_GET(lib, (vis_t), ((foo), (adl_barrier), (export_me_function)), (vis_t, vis_t)); That way we can use macro metaprogramming too. And use any compile-time mangling facilities I'd really like compiler vendors to add (e.g. http://llvm.org/bugs/show_bug.cgi?id=21263).
// mangle_get method has type of the variable and it's full name, // so a Mangler could create a correct mangled name without forward declaration auto v = lib.mangle_get
("foo::adl_barrier::export_me_variable");
You might find the following of interest Antony. If you remember my local namespace binding tool I am intending to split off Boost libraries so they are standalone, such forked Boost library headers might take something resembling the following preamble: #include "local-bind-cpp-library/include/import.hpp" #define BOOST_SPINLOCK_V1 (boost), (spinlock), (v1, inline) #ifndef BOOST_SPINLOCK_V1_STL11_IMPL #define BOOST_SPINLOCK_V1_STL11_IMPL std #endif #define BOOST_SPINLOCK_V1_NAMESPACE BOOST_LOCAL_BIND_NAMESPACE (BOOST_SPINLOCK_V1) #define BOOST_SPINLOCK_V1_NAMESPACE_BEGIN BOOST_LOCAL_BIND_NAMESPACE_BEGIN(BOOST_SPINLOCK_V1) #define BOOST_SPINLOCK_V1_NAMESPACE_END BOOST_LOCAL_BIND_NAMESPACE_END (BOOST_SPINLOCK_V1) #define BOOST_STL11_ATOMIC_MAP_NAMESPACE_BEGIN BOOST_LOCAL_BIND_NAMESPACE_BEGIN(BOOST_SPINLOCK_V1, (stl11, inline)) #define BOOST_STL11_ATOMIC_MAP_NAMESPACE_END BOOST_LOCAL_BIND_NAMESPACE_END (BOOST_SPINLOCK_V1, (stl11, inline)) #define BOOST_STL11_CHRONO_MAP_NAMESPACE_BEGIN BOOST_LOCAL_BIND_NAMESPACE_BEGIN(BOOST_SPINLOCK_V1, (stl11, inline), (chrono)) #define BOOST_STL11_CHRONO_MAP_NAMESPACE_END BOOST_LOCAL_BIND_NAMESPACE_END (BOOST_SPINLOCK_V1, (stl11, inline), (chrono)) #define BOOST_STL11_MUTEX_MAP_NAMESPACE_BEGIN BOOST_LOCAL_BIND_NAMESPACE_BEGIN(BOOST_SPINLOCK_V1, (stl11, inline)) #define BOOST_STL11_MUTEX_MAP_NAMESPACE_END BOOST_LOCAL_BIND_NAMESPACE_END (BOOST_SPINLOCK_V1, (stl11, inline)) #define BOOST_STL11_THREAD_MAP_NAMESPACE_BEGIN BOOST_LOCAL_BIND_NAMESPACE_BEGIN(BOOST_SPINLOCK_V1, (stl11, inline)) #define BOOST_STL11_THREAD_MAP_NAMESPACE_END BOOST_LOCAL_BIND_NAMESPACE_END (BOOST_SPINLOCK_V1, (stl11, inline)) #include BOOST_LOCAL_BIND_INCLUDE_STL11(BOOST_SPINLOCK_V1_STL11_IMPL, atomic) #include BOOST_LOCAL_BIND_INCLUDE_STL11(BOOST_SPINLOCK_V1_STL11_IMPL, chrono) #include BOOST_LOCAL_BIND_INCLUDE_STL11(BOOST_SPINLOCK_V1_STL11_IMPL, mutex) #include BOOST_LOCAL_BIND_INCLUDE_STL11(BOOST_SPINLOCK_V1_STL11_IMPL, thread) BOOST_SPINLOCK_V1_NAMESPACE_BEGIN BOOST_LOCAL_BIND_DECLARE(BOOST_SPINLOCK_V1) ... normal header stuff ... BOOST_SPINLOCK_V1_NAMESPACE_END You can see a real example at https://github.com/ned14/boost.spinlock/blob/expected_future/include/s pinlock.hpp#L68 What the above does is to allow the following: 1. External code can choose the C++ STL 11 implementation, boost or std, using BOOST_SPINLOCK_V1_STL11_IMPL. Those are bound directly into the boost::spinlock::v1 namespace. 2. Multiple versions of Boost.Spinlock can coexist in the same process thanks to C++ 11's inline namespaces 3. Multiple variants of Boost.Spinlock (e.g. one with boost, one with std) can also coexist in the same process. There is a minor bug in the above macro metaprogramming about that, but it's on my todo, it'll work right soon. I also have realised that local namespace bindings are really your library *exactly* specifying its dependencies, so I now have a new way of importing a bind-capable library directly into your library without affecting other libraries i.e. Library A can import Boost.Spinlock v1.01 using the std C++ 11 STL while Library B can import Boost Spinlock v1.02 using the boost C++ 11 STL and it all "just works" plus Library A's configuration does not interfere with Library B's configuration. To therefore import locally, not globally to all the code which includes your header file, you do: #define BOOST_SPINLOCK_MAP_NAMESPACE_BEGIN BOOST_LOCAL_BIND_NAMESPACE_BEGIN(MY_NAMESPACE, (spinlock)) #define BOOST_SPINLOCK_MAP_NAMESPACE_END BOOST_LOCAL_BIND_NAMESPACE_END (MY_NAMESPACE, (spinlock)) #include "boost/spinlock.hpp" This gains us a poor man's implementation of C++ 17 Modules today using namespace trickery. I think it's pretty neato. There are quite a few opportunites for Boost.DLL here, because I tag bind-capable namespaces so they can be identified by examining the binary. I see no reason why the bindings generator couldn't also spit out an inspection function, then a program can very easily inspect a library and say *exactly* what its dependencies are and moreover, *exactly* what depends on that library. That helps solve the packaging and distribution problem. More info explaining the above macro programming at the newly updated Readme at https://github.com/ned14/local-bind-cpp-library. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/