diff base/ById.h @ 1752:6d09d68165a4 by-id

Further review of ById: make IDs only available when adding a model to the ById store, not by querying the item directly. This means any id encountered in the wild must have been added to the store at some point (even if later released), which simplifies reasoning about lifecycles
author Chris Cannam
date Fri, 05 Jul 2019 15:28:07 +0100
parents d0ef65d8dd89
children d954dfccd922
line wrap: on
line diff
--- a/base/ById.h	Thu Jul 04 18:04:21 2019 +0100
+++ b/base/ById.h	Fri Jul 05 15:28:07 2019 +0100
@@ -95,6 +95,9 @@
     virtual ~WithId() {
     }
 
+protected:
+    friend class AnyById;
+    
     /**
      * Return an id for this object. The id is a unique number for
      * this object among all objects that implement WithId within this
@@ -116,6 +119,10 @@
     
     WithTypedId() : WithId() { }
 
+protected:
+    template <typename Item, typename Id>
+    friend class TypedById;
+    
     /**
      * Return an id for this object. The id is a unique value for this
      * object among all objects that implement WithTypedId within this
@@ -131,7 +138,7 @@
 class AnyById
 {
 public:
-    static void add(int, std::shared_ptr<WithId>);
+    static int add(std::shared_ptr<WithId>);
     static void release(int);
     static std::shared_ptr<WithId> get(int); 
 
@@ -157,11 +164,8 @@
 {
 public:
     static Id add(std::shared_ptr<Item> item) {
-        auto id = item->getId();
-        if (id.isNone()) {
-            throw std::logic_error("item id should never be None");
-        }
-        AnyById::add(id.untyped, item);
+        Id id;
+        id.untyped = AnyById::add(item);
         return id;
     }
 
@@ -185,7 +189,7 @@
     static std::shared_ptr<Item> get(Id id) {
         return getAs<Item>(id);
     }
-
+    
     /**
      * If the Item type is an XmlExportable, return the export ID of
      * the given item ID. A call to this function will fail to compile