
Francisco José Tapia
Hi Jeremy
Thanks by your interest in the library
About the interface with Multi Index, I think it's a good idea, but I think first we must build a robust library with all the functionality, and to be checked by the Boost users, and after export ideas and code to others libraries. I insist in the checking of the users for don't export bugs and problems.
It is reasonable to not want to deal with the added complexity of Multi Index initially, though if you decide to add it later it seems you would either have to maintain two copies of the code, or make the non Multi Index version just a wrapper over Multi Index.
About the synchronization, my idea is to do a lock-free data structure from the user view-point. The locks are automatic, and don't be managed by the users. The users don' need lock, only must take care about what they want to do. But for a safe code they must use the new functions.
The basic issue is that if you want the user to not have to worry about locking, then you must perfectly anticipate precisely which operations the user needs to appear atomic. You have added various predicate-enabled operations, but there is no guarantee that one of those happens to fit what the user needs. For example: - the user may want to perform some combined insert/erase operation and have it appear atomic to other threads; - any use of iterator traversal will require manual locking by the user; - the user may want to atomically combine modifications to the data structure with modifications to the values in the data structure; - the user may need to atomically modify multiple data structures.
From my perspective, forcing users writing multithreaded code to think carefully about synchronization/locking is a good thing. It is true that
x.insert_if(..., [&]{ // check some stuff here }); is shorter than { std::lock_guardstd::mutex guard(my_mutex); if (/* check some stuff here */) { x.insert(...); } } but it isn't that much shorter, and the second version is more straightforward and is much more general. Perhaps others agree with you though that having a convenience interface for users, even if it is limited in capability, is still useful. One small comment regarding your interface of predicate-enabled functions is to pass functors using a template type, like the standard library and other boost libraries generally do, rather than using std::function, as std::function introduces extra overhead.