{"action":"created","issue":{"url":"https://api.github.com/repos/simbody/simbody/issues/327","labels_url":"https://api.github.com/repos/simbody/simbody/issues/327/labels{/name}","comments_url":"https://api.github.com/repos/simbody/simbody/issues/327/comments","events_url":"https://api.github.com/repos/simbody/simbody/issues/327/events","html_url":"https://github.com/simbody/simbody/pull/327","id":54847315,"number":327,"title":"Add copy-on-write smart pointer CloneOnWritePtr","user":{"login":"sherm1","id":4088016,"avatar_url":"https://avatars.githubusercontent.com/u/4088016?v=3","gravatar_id":"","url":"https://api.github.com/users/sherm1","html_url":"https://github.com/sherm1","followers_url":"https://api.github.com/users/sherm1/followers","following_url":"https://api.github.com/users/sherm1/following{/other_user}","gists_url":"https://api.github.com/users/sherm1/gists{/gist_id}","starred_url":"https://api.github.com/users/sherm1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sherm1/subscriptions","organizations_url":"https://api.github.com/users/sherm1/orgs","repos_url":"https://api.github.com/users/sherm1/repos","events_url":"https://api.github.com/users/sherm1/events{/privacy}","received_events_url":"https://api.github.com/users/sherm1/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":3,"created_at":"2015-01-20T06:07:07Z","updated_at":"2015-01-20T06:46:00Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/simbody/simbody/pulls/327","html_url":"https://github.com/simbody/simbody/pull/327","diff_url":"https://github.com/simbody/simbody/pull/327.diff","patch_url":"https://github.com/simbody/simbody/pull/327.patch"},"body":"Simbody already has a `ClonePtr` which is like `std::unique_ptr` but with deep copy semantics (`std::unique_ptr` doesn't allow copying). This PR adds another smart pointer `CloneOnWritePtr` that acts like `std::shared_ptr` when the managed object is being shared for reading, but acts like `ClonePtr` when someone tries to write on it. That means that it is very fast to copy construct or copy assign, because no copy actually occurs until someone tries to write. At that point the managed object's `clone()` method gets called and the writer ends up writing on their own private copy, while all the other sharers see the use count decremented.\r\n\r\nThis should allow for very fast copying of complicated objects like States where large chunks of the object remain unchanged from source to copy. In particular, discrete state variables are unchanged while integrators need to make trial copies of the continuous ones.\r\n\r\nNote: I modeled this as closely as possible on C++11 smart pointers rather than on the existing `ClonePtr` which needs to be upgraded to match C++11 better."},"comment":{"url":"https://api.github.com/repos/simbody/simbody/issues/comments/70611412","html_url":"https://github.com/simbody/simbody/pull/327#issuecomment-70611412","issue_url":"https://api.github.com/repos/simbody/simbody/issues/327","id":70611412,"user":{"login":"sherm1","id":4088016,"avatar_url":"https://avatars.githubusercontent.com/u/4088016?v=3","gravatar_id":"","url":"https://api.github.com/users/sherm1","html_url":"https://github.com/sherm1","followers_url":"https://api.github.com/users/sherm1/followers","following_url":"https://api.github.com/users/sherm1/following{/other_user}","gists_url":"https://api.github.com/users/sherm1/gists{/gist_id}","starred_url":"https://api.github.com/users/sherm1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sherm1/subscriptions","organizations_url":"https://api.github.com/users/sherm1/orgs","repos_url":"https://api.github.com/users/sherm1/repos","events_url":"https://api.github.com/users/sherm1/events{/privacy}","received_events_url":"https://api.github.com/users/sherm1/received_events","type":"User","site_admin":false},"created_at":"2015-01-20T06:46:00Z","updated_at":"2015-01-20T06:46:00Z","body":">  The OpenSim code contains about 49 const_casts. I didn't search exhaustively, but here's a const-cast on a state object.\r\n\r\nProbably some of those are OK and some aren't. But they wouldn't affect the copy-on-write activity of the `CloneOnWritePtr` class. To mess that up, you actually have to extract a const pointer from it and then const_cast it. That would be a foolish thing to do to an object whose whole purpose in life is to use read-vs-write as a way to avoid copying."}}