diff options
author | Boris Kolpackov <boris@codesynthesis.com> | 2012-06-18 09:32:09 +0200 |
---|---|---|
committer | Boris Kolpackov <boris@codesynthesis.com> | 2012-06-18 09:32:09 +0200 |
commit | fe625c9b53fa6b251cdc1c7ed5778ccd4dfeefa8 (patch) | |
tree | f141d7b69b9f193c7ad97c8dc7b4c3a05cb6d81a | |
parent | 0ab918e8b3660aed2e24d543633da54cf698b72f (diff) |
Allocate container traits lazily and only when their definition is seen
This fixes a problem with polymorphic hierarchies spread over multiple
files in which case the source code for the derived class does not have
the definition of the container traits for the base class. See the comment
in the source code for further details.
-rw-r--r-- | odb/mssql/polymorphic-object-statements.hxx | 5 | ||||
-rw-r--r-- | odb/mssql/polymorphic-object-statements.txx | 1 | ||||
-rw-r--r-- | odb/mssql/simple-object-statements.hxx | 57 | ||||
-rw-r--r-- | odb/mssql/simple-object-statements.txx | 1 |
4 files changed, 58 insertions, 6 deletions
diff --git a/odb/mssql/polymorphic-object-statements.hxx b/odb/mssql/polymorphic-object-statements.hxx index 0d70ae4..79e9875 100644 --- a/odb/mssql/polymorphic-object-statements.hxx +++ b/odb/mssql/polymorphic-object-statements.hxx @@ -336,7 +336,7 @@ namespace odb container_statement_cache_type& container_statment_cache () { - return container_statement_cache_; + return container_statement_cache_.get (conn_); } public: @@ -368,7 +368,8 @@ namespace odb root_statements_type& root_statements_; base_statements_type& base_statements_; - container_statement_cache_type container_statement_cache_; + container_statement_cache_ptr<container_statement_cache_type> + container_statement_cache_; image_type image_; diff --git a/odb/mssql/polymorphic-object-statements.txx b/odb/mssql/polymorphic-object-statements.txx index 87ed696..9a9e4c0 100644 --- a/odb/mssql/polymorphic-object-statements.txx +++ b/odb/mssql/polymorphic-object-statements.txx @@ -63,7 +63,6 @@ namespace odb : statements_base (conn), root_statements_ (conn.statement_cache ().find_object<root_type> ()), base_statements_ (conn.statement_cache ().find_object<base_type> ()), - container_statement_cache_ (conn), insert_image_binding_ (insert_image_bind_, insert_column_count), update_image_binding_ (update_image_bind_, update_column_count + id_column_count) diff --git a/odb/mssql/simple-object-statements.hxx b/odb/mssql/simple-object-statements.hxx index d4809b4..7002ecb 100644 --- a/odb/mssql/simple-object-statements.hxx +++ b/odb/mssql/simple-object-statements.hxx @@ -29,6 +29,58 @@ namespace odb { namespace mssql { + // The container_statement_cache class is only defined (and used) in + // the generated source file. However, object_statements may be + // referenced from another source file in the case of a polymorphic + // hierarchy (though in this case the container statement cache is + // not used). As a result, we cannot have a by-value member and + // instead will store a pointer and lazily allocate the cache if + // and when needed. We will also need to store a pointer to the + // deleter function which will be initialized during allocation + // (at that point we know that the cache class is defined). + // + template <typename T> + struct container_statement_cache_ptr + { + typedef mssql::connection connection_type; + + container_statement_cache_ptr (): p_ (0) {} + ~container_statement_cache_ptr () {if (p_ != 0) (this->*deleter_) (0);} + + T& + get (connection_type& c) + { + if (p_ == 0) + allocate (&c); + + return *p_; + } + + private: + void + allocate (connection_type*); + + private: + T* p_; + void (container_statement_cache_ptr::*deleter_) (connection_type*); + }; + + template <typename T> + void container_statement_cache_ptr<T>:: + allocate (connection_type* c) + { + // To reduce object code size, this function acts as both allocator + // and deleter. + // + if (p_ == 0) + { + p_ = new T (*c); + deleter_ = &container_statement_cache_ptr<T>::allocate; + } + else + delete p_; + } + // // Implementation for objects with object id. // @@ -356,7 +408,7 @@ namespace odb container_statement_cache_type& container_statment_cache () { - return container_statement_cache_; + return container_statement_cache_.get (conn_); } public: @@ -394,7 +446,8 @@ namespace odb clear_delayed_ (); private: - container_statement_cache_type container_statement_cache_; + container_statement_cache_ptr<container_statement_cache_type> + container_statement_cache_; image_type image_; diff --git a/odb/mssql/simple-object-statements.txx b/odb/mssql/simple-object-statements.txx index 6620c40..2cac2de 100644 --- a/odb/mssql/simple-object-statements.txx +++ b/odb/mssql/simple-object-statements.txx @@ -42,7 +42,6 @@ namespace odb object_statements<T>:: object_statements (connection_type& conn) : object_statements_base (conn), - container_statement_cache_ (conn), select_image_binding_ (select_image_bind_, select_column_count), insert_image_binding_ (insert_image_bind_, insert_column_count), update_image_binding_ (update_image_bind_, |