aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE2
-rw-r--r--makefile4
-rw-r--r--manifest6
-rw-r--r--odb/database.hxx2
-rw-r--r--odb/details/function-wrapper.txx5
-rw-r--r--odb/details/transfer-ptr.hxx2
-rw-r--r--odb/details/unique-ptr.hxx4
-rw-r--r--odb/lazy-ptr-impl.hxx8
-rw-r--r--odb/lazy-ptr-impl.ixx8
-rw-r--r--odb/lazy-ptr.hxx8
-rw-r--r--odb/lazy-ptr.ixx8
-rw-r--r--odb/makefile2
-rw-r--r--odb/nested-container.hxx178
-rw-r--r--odb/traits.hxx12
-rw-r--r--odb/vector-impl.hxx4
-rw-r--r--odb/vector-impl.ixx53
-rw-r--r--odb/vector.hxx8
-rw-r--r--odb/version-build2.hxx.in2
-rw-r--r--odb/version.hxx8
-rw-r--r--version1
-rw-r--r--version.txt1
21 files changed, 230 insertions, 96 deletions
diff --git a/LICENSE b/LICENSE
index 9678900..9d92da1 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2009-2021 Code Synthesis Tools CC.
+Copyright (c) 2009-2024 Code Synthesis Tools CC.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
diff --git a/makefile b/makefile
index 9376c02..74e1b6e 100644
--- a/makefile
+++ b/makefile
@@ -12,12 +12,12 @@ clean := $(out_base)/.clean
$(default): $(addprefix $(out_base)/,$(addsuffix /,$(dirs)))
$(dist): export dirs := $(dirs)
-$(dist): export docs := GPLv2 LICENSE README NEWS version
+$(dist): export docs := GPLv2 LICENSE README NEWS version.txt
$(dist): data_dist := INSTALL libodb-vc8.sln libodb-vc9.sln libodb-vc10.sln \
libodb-vc11.sln libodb-vc12.sln
$(dist): exec_dist := bootstrap
$(dist): export extra_dist := $(data_dist) $(exec_dist)
-$(dist): export version = $(shell cat $(src_root)/version)
+$(dist): export version = $(shell cat $(src_root)/version.txt)
$(dist): $(addprefix $(out_base)/,$(addsuffix /.dist,$(dirs)))
$(call dist-data,$(docs) $(data_dist) libodb.pc.in)
diff --git a/manifest b/manifest
index 8472d9e..d728912 100644
--- a/manifest
+++ b/manifest
@@ -1,6 +1,6 @@
: 1
name: libodb
-version: 2.5.0-b.22.z
+version: 2.5.0-b.26.z
project: odb
summary: Common ODB runtime library
license: GPL-2.0-only
@@ -15,5 +15,5 @@ email: odb-users@codesynthesis.com
build-warning-email: odb-builds@codesynthesis.com
builds: all
requires: c++11
-depends: * build2 >= 0.14.0-
-depends: * bpkg >= 0.14.0-
+depends: * build2 >= 0.16.0-
+depends: * bpkg >= 0.16.0-
diff --git a/odb/database.hxx b/odb/database.hxx
index 485cf52..e18e8ee 100644
--- a/odb/database.hxx
+++ b/odb/database.hxx
@@ -48,6 +48,8 @@ namespace odb
#ifdef ODB_CXX11
//database (database&&) = default; // VC 2013
+ // Note: noexcept is not specified since *_map_ (std::map) can throw.
+ //
database (database&& d)
: id_ (d.id_),
tracer_ (d.tracer_),
diff --git a/odb/details/function-wrapper.txx b/odb/details/function-wrapper.txx
index 19e4cbc..db73e8d 100644
--- a/odb/details/function-wrapper.txx
+++ b/odb/details/function-wrapper.txx
@@ -67,7 +67,10 @@ namespace odb
}
else
{
- function = reinterpret_cast<F*> (&caller_impl<F>::function);
+ function_wrapper<decltype (caller_impl<F>::function)> fw (
+ &caller_impl<F>::function);
+
+ function = fw.template cast<F*> ();
deleter = &deleter_impl<F>;
std_function = new std_function_type (std::move (sf));
}
diff --git a/odb/details/transfer-ptr.hxx b/odb/details/transfer-ptr.hxx
index 2ee0752..4b63df6 100644
--- a/odb/details/transfer-ptr.hxx
+++ b/odb/details/transfer-ptr.hxx
@@ -49,7 +49,7 @@ namespace odb
transfer_ptr& operator= (const transfer_ptr&);
public:
- transfer_ptr (transfer_ptr&& p): p_ (p.transfer ()) {}
+ transfer_ptr (transfer_ptr&& p) noexcept: p_ (p.transfer ()) {}
#endif
~transfer_ptr () {delete p_;}
diff --git a/odb/details/unique-ptr.hxx b/odb/details/unique-ptr.hxx
index 6663c30..06b2c76 100644
--- a/odb/details/unique-ptr.hxx
+++ b/odb/details/unique-ptr.hxx
@@ -22,8 +22,8 @@ namespace odb
~unique_ptr () {delete p_;}
#ifdef ODB_CXX11
- unique_ptr (unique_ptr&& p): p_ (p.p_) {p.p_ = 0;}
- unique_ptr& operator= (unique_ptr&& p)
+ unique_ptr (unique_ptr&& p) noexcept: p_ (p.p_) {p.p_ = 0;}
+ unique_ptr& operator= (unique_ptr&& p) noexcept
{
if (this != &p)
{
diff --git a/odb/lazy-ptr-impl.hxx b/odb/lazy-ptr-impl.hxx
index 83d6011..89fe798 100644
--- a/odb/lazy-ptr-impl.hxx
+++ b/odb/lazy-ptr-impl.hxx
@@ -44,10 +44,10 @@ namespace odb
//
public:
#ifdef ODB_CXX11
- lazy_ptr_base (lazy_ptr_base&&);
+ lazy_ptr_base (lazy_ptr_base&&) noexcept;
lazy_ptr_base&
- operator= (lazy_ptr_base&&);
+ operator= (lazy_ptr_base&&) noexcept;
#endif
public:
@@ -139,13 +139,13 @@ namespace odb
//
public:
#ifdef ODB_CXX11
- lazy_ptr_impl (lazy_ptr_impl&&);
+ lazy_ptr_impl (lazy_ptr_impl&&) noexcept;
template <typename Y>
lazy_ptr_impl (lazy_ptr_impl<Y>&&);
lazy_ptr_impl&
- operator= (lazy_ptr_impl&&);
+ operator= (lazy_ptr_impl&&) noexcept;
template <typename Y>
lazy_ptr_impl&
diff --git a/odb/lazy-ptr-impl.ixx b/odb/lazy-ptr-impl.ixx
index 7843dc9..9ab0471 100644
--- a/odb/lazy-ptr-impl.ixx
+++ b/odb/lazy-ptr-impl.ixx
@@ -31,7 +31,7 @@ namespace odb
#ifdef ODB_CXX11
inline lazy_ptr_base::
- lazy_ptr_base (lazy_ptr_base&& r)
+ lazy_ptr_base (lazy_ptr_base&& r) noexcept
: id_ (r.id_), db_ (r.db_), loader_ (r.loader_),
free_ (r.free_), copy_ (r.copy_)
{
@@ -78,7 +78,7 @@ namespace odb
#ifdef ODB_CXX11
inline lazy_ptr_base& lazy_ptr_base::
- operator= (lazy_ptr_base&& r)
+ operator= (lazy_ptr_base&& r) noexcept
{
if (id_ != r.id_)
{
@@ -272,7 +272,7 @@ namespace odb
#ifdef ODB_CXX11
template <typename T>
inline lazy_ptr_impl<T>::
- lazy_ptr_impl (lazy_ptr_impl&& r)
+ lazy_ptr_impl (lazy_ptr_impl&& r) noexcept
: lazy_ptr_base (std::move (r))
{
}
@@ -287,7 +287,7 @@ namespace odb
template <typename T>
inline lazy_ptr_impl<T>& lazy_ptr_impl<T>::
- operator= (lazy_ptr_impl&& r)
+ operator= (lazy_ptr_impl&& r) noexcept
{
lazy_ptr_base& b (*this);
b = std::move (r);
diff --git a/odb/lazy-ptr.hxx b/odb/lazy-ptr.hxx
index ae2b43c..ab31dfc 100644
--- a/odb/lazy-ptr.hxx
+++ b/odb/lazy-ptr.hxx
@@ -246,14 +246,14 @@ namespace odb
lazy_unique_ptr (pointer, const deleter_type&) /*noexcept*/;
lazy_unique_ptr (pointer, deleter_type&&) /*noexcept*/;
- lazy_unique_ptr (lazy_unique_ptr&&) /*noexcept*/;
+ lazy_unique_ptr (lazy_unique_ptr&&) noexcept;
template <class T1, class D1> lazy_unique_ptr (lazy_unique_ptr<T1, D1>&&) /*noexcept*/;
//template <class T1> lazy_unique_ptr (std::auto_ptr<T1>&&) /*noexcept*/;
#ifdef ODB_CXX11_NULLPTR
lazy_unique_ptr& operator= (std::nullptr_t) /*noexcept*/;
#endif
- lazy_unique_ptr& operator= (lazy_unique_ptr&&) /*noexcept*/;
+ lazy_unique_ptr& operator= (lazy_unique_ptr&&) noexcept;
template <class T1, class D1> lazy_unique_ptr& operator= (lazy_unique_ptr<T1, D1>&&) /*noexcept*/;
T& operator* () const;
@@ -407,7 +407,7 @@ namespace odb
lazy_shared_ptr (const lazy_shared_ptr&) /*noexcept*/;
template <class Y> lazy_shared_ptr (const lazy_shared_ptr<Y>&) /*noexcept*/;
- lazy_shared_ptr (lazy_shared_ptr&&) /*noexcept*/;
+ lazy_shared_ptr (lazy_shared_ptr&&) noexcept;
template <class Y> lazy_shared_ptr (lazy_shared_ptr<Y>&&) /*noexcept*/;
template <class Y> explicit lazy_shared_ptr (const lazy_weak_ptr<Y>&);
//template <class Y> explicit lazy_shared_ptr (std::auto_ptr<Y>&&);
@@ -417,7 +417,7 @@ namespace odb
lazy_shared_ptr& operator= (const lazy_shared_ptr&) /*noexcept*/;
template <class Y> lazy_shared_ptr& operator= (const lazy_shared_ptr<Y>&) /*noexcept*/;
- lazy_shared_ptr& operator= (lazy_shared_ptr&&) /*noexcept*/;
+ lazy_shared_ptr& operator= (lazy_shared_ptr&&) noexcept;
template <class Y> lazy_shared_ptr& operator= (lazy_shared_ptr<Y>&&) /*noexcept*/;
//template <class Y> lazy_shared_ptr& operator= (std::auto_ptr<Y>&&);
template <class Y, class D> lazy_shared_ptr& operator= (std::unique_ptr<Y, D>&&);
diff --git a/odb/lazy-ptr.ixx b/odb/lazy-ptr.ixx
index 647db83..a2d72f5 100644
--- a/odb/lazy-ptr.ixx
+++ b/odb/lazy-ptr.ixx
@@ -519,7 +519,7 @@ namespace odb
template <class T, class D>
lazy_unique_ptr<T, D>::
- lazy_unique_ptr (lazy_unique_ptr&& r)
+ lazy_unique_ptr (lazy_unique_ptr&& r) noexcept
: p_ (std::move (r.p_)), i_ (std::move (r.i_)) {}
template <class T, class D>
@@ -545,7 +545,7 @@ namespace odb
template <class T, class D>
lazy_unique_ptr<T, D>& lazy_unique_ptr<T, D>::
- operator= (lazy_unique_ptr&& r)
+ operator= (lazy_unique_ptr&& r) noexcept
{
p_ = std::move (r.p_);
i_ = std::move (r.i_);
@@ -922,7 +922,7 @@ namespace odb
template <class T>
inline lazy_shared_ptr<T>::
- lazy_shared_ptr (lazy_shared_ptr&& r)
+ lazy_shared_ptr (lazy_shared_ptr&& r) noexcept
: p_ (std::move (r.p_)), i_ (std::move (r.i_)) {}
template <class T>
@@ -979,7 +979,7 @@ namespace odb
template <class T>
inline lazy_shared_ptr<T>& lazy_shared_ptr<T>::
- operator= (lazy_shared_ptr&& r)
+ operator= (lazy_shared_ptr&& r) noexcept
{
p_ = std::move (r.p_);
i_ = std::move (r.i_);
diff --git a/odb/makefile b/odb/makefile
index a5e30f5..01b395e 100644
--- a/odb/makefile
+++ b/odb/makefile
@@ -136,7 +136,7 @@ libodb-vc10.vcxproj libodb-vc10.vcxproj.filters \
libodb-vc11.vcxproj libodb-vc11.vcxproj.filters \
libodb-vc12.vcxproj libodb-vc12.vcxproj.filters
$(dist): export interface_version = $(shell sed -e \
-'s/^\([0-9]*\.[0-9]*\).*/\1/' $(src_root)/version)
+'s/^\([0-9]*\.[0-9]*\).*/\1/' $(src_root)/version.txt)
$(dist):
$(call dist-data,$(sources) $(posix_threads_sources) \
diff --git a/odb/nested-container.hxx b/odb/nested-container.hxx
index c7627ed..d7e4ec1 100644
--- a/odb/nested-container.hxx
+++ b/odb/nested-container.hxx
@@ -19,22 +19,29 @@ namespace odb
{
// Nested container emulation support for ODB.
//
- // Note that the outer key in the inner container should strictly
- // speaking be a foreign key pointing to the key of the outer
- // container. The only way to achieve this currently is to manually
- // add the constraint via ALTER TABLE ADD CONSTRAINT. Note, however,
- // that as long as we only modify these tables via the ODB container
- // interface, not having the foreign key (and not having ON DELETE
- // CASCADE) should be harmless (since we have a foreign key pointing
- // to the object id).
+ // In a nutshell, the idea is to represent a nested container, for example,
+ // vector<vector<V>>, as map<nested_key, V> where nested_key is a composite
+ // key consisting of the outer and inner container indexes.
//
-
- // Map key that is used to emulate nested container mapping in ODB.
- // Template parameter T is a tag that allows us to distinguish keys
- // for unrelated containers in order to assign column names, etc.
- // Use inner container type for T.
+ // Note that with this approach the empty trailing entries of the outer
+ // container will not be added on load. It is assumed that the user handles
+ // that on their own, for example, by pre-loading the outer container entry
+ // members if there are any.
+ //
+ // Also note that the outer key in the inner container should strictly
+ // speaking be a foreign key pointing to the key of the outer container. The
+ // only way to achieve this currently is to manually add the constraint via
+ // ALTER TABLE ADD CONSTRAINT. Note, however, that as long as we only modify
+ // these tables via the ODB container interface, not having the foreign key
+ // (and not having ON DELETE CASCADE) should be harmless (since we have a
+ // foreign key pointing to the object id).
+
+ // Map key that is used to emulate 1-level nested container mapping (for
+ // example, vector<vector<V>>). Template parameter IC is a tag that allows
+ // us to distinguish keys for unrelated containers in order to assign column
+ // names, etc. Use the inner container type (for example, vector<V>) for IC.
//
- template <typename T,
+ template <typename IC,
typename O = std::size_t,
typename I = std::size_t>
struct nested_key
@@ -54,10 +61,40 @@ namespace odb
return outer < v.outer || (outer == v.outer && inner < v.inner);
}
};
+
+ // Map key that is used to emulate 2-level nested container mapping (for
+ // example, vector<vector<vector<V>>>>). Use the middle container type for
+ // MC (for example, vector<vector<V>>).
+ //
+ template <typename MC,
+ typename O = std::size_t,
+ typename M = std::size_t,
+ typename I = std::size_t>
+ struct nested2_key
+ {
+ using outer_type = O;
+ using middle_type = M;
+ using inner_type = I;
+
+ outer_type outer;
+ middle_type middle;
+ inner_type inner;
+
+ nested2_key () = default;
+ nested2_key (outer_type o, middle_type m, inner_type i)
+ : outer (o), middle (m), inner (i) {}
+
+ bool
+ operator< (const nested2_key& v) const
+ {
+ return outer != v.outer ? outer < v.outer :
+ middle != v.middle ? middle < v.middle :
+ inner < v.inner ;
+ }
+ };
}
#include <map>
-#include <vector>
#include <cstddef> // size_t
#include <utility> // move(), declval()
#include <cassert>
@@ -65,46 +102,113 @@ namespace odb
namespace odb
{
- // vector<vector<>>
- //
- template <typename IC>
- struct nested_value_type:
- std::remove_reference<decltype (std::declval<IC> ()[0])> {};
+ template <typename C>
+ struct nested1_type:
+ std::remove_reference<decltype (std::declval<C> ()[0])> {};
+
+ template <typename C>
+ struct nested2_type:
+ std::remove_reference<decltype (std::declval<C> ()[0][0])> {};
+
+ template <typename C>
+ struct nested3_type:
+ std::remove_reference<decltype (std::declval<C> ()[0][0][0])> {};
- template <typename IC>
- std::map<nested_key<IC>, typename nested_value_type<IC>::type>
- nested_get (const std::vector<IC>& v)
+ // 1-level nesting.
+ //
+ template <typename OC> // For example, OC = vector<vector<V>>.
+ std::map<nested_key<typename nested1_type<OC>::type>,
+ typename nested2_type<OC>::type>
+ nested_get (const OC& oc)
{
using namespace std;
- using I = typename nested_value_type<IC>::type;
+ using IC = typename nested1_type<OC>::type;
+ using V = typename nested2_type<OC>::type;
using K = nested_key<IC>;
- map<K, I> r;
- for (size_t n (0); n != v.size (); ++n)
+ map<K, V> r;
+ for (size_t o (0); o != oc.size (); ++o)
+ {
+ const IC& ic (oc[o]);
+ for (size_t i (0); i != ic.size (); ++i)
+ r.emplace (K (o, i), ic[i]);
+ }
+ return r;
+ }
+
+ template <typename K, typename V, typename OC>
+ void
+ nested_set (OC& oc, std::map<K, V>&& r)
+ {
+ using namespace std;
+
+ for (auto& p: r)
+ {
+ size_t o (p.first.outer);
+ size_t i (p.first.inner);
+ V& v (p.second);
+
+ if (o >= oc.size ())
+ oc.resize (o + 1);
+
+ assert (i == oc[o].size ());
+
+ oc[o].push_back (move (v));
+ }
+ }
+
+ // 2-level nesting.
+ //
+ template <typename OC> // For example, OC = vector<vector<vector<V>>>.
+ std::map<nested2_key<typename nested1_type<OC>::type>,
+ typename nested3_type<OC>::type>
+ nested2_get (const OC& oc)
+ {
+ using namespace std;
+
+ using MC = typename nested1_type<OC>::type;
+ using V = typename nested3_type<OC>::type;
+ using K = nested2_key<MC>;
+
+ map<K, V> r;
+ for (size_t o (0); o != oc.size (); ++o)
{
- const IC& o (v[n]);
- for (size_t m (0); m != o.size (); ++m)
- r.emplace (K (n, m), o[m]);
+ const auto& mc (oc[o]);
+ for (size_t m (0); m != mc.size (); ++m)
+ {
+ const auto& ic (mc[m]);
+ for (size_t i (0); i != ic.size (); ++i)
+ r.emplace (K (o, m, i), ic[i]);
+ }
}
return r;
}
- template <typename K, typename I, typename IC>
+ template <typename K, typename V, typename OC>
void
- nested_set (std::vector<IC>& v, std::map<K, I>&& r)
+ nested2_set (OC& oc, std::map<K, V>&& r)
{
using namespace std;
for (auto& p: r)
{
- size_t n (p.first.outer);
- size_t m (p.first.inner);
- I& i (p.second);
+ size_t o (p.first.outer);
+ size_t m (p.first.middle);
+ size_t i (p.first.inner);
+ V& v (p.second);
+
+ if (o >= oc.size ())
+ oc.resize (o + 1);
+
+ auto& mc (oc[o]);
+
+ if (m >= mc.size ())
+ mc.resize (m + 1);
+
+ assert (i == mc[m].size ());
- assert (n < v.size ());
- assert (m == v[n].size ());
- v[n].push_back (move (i));
+ mc[m].push_back (move (v));
}
}
}
diff --git a/odb/traits.hxx b/odb/traits.hxx
index 1cb2613..2c6f5d6 100644
--- a/odb/traits.hxx
+++ b/odb/traits.hxx
@@ -71,6 +71,14 @@ namespace odb
typedef T value_type;
typedef P pointer_type;
+
+ // Suppress bogus use-after-free introduced in GCC 12 (GCC bug #105327).
+ //
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wuse-after-free"
+#endif
+
static P
create ()
{
@@ -81,6 +89,10 @@ namespace odb
return p;
}
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ >= 12
+#pragma GCC diagnostic pop
+#endif
+
private:
struct mem_guard
{
diff --git a/odb/vector-impl.hxx b/odb/vector-impl.hxx
index 5189395..9f2ea7c 100644
--- a/odb/vector-impl.hxx
+++ b/odb/vector-impl.hxx
@@ -45,7 +45,7 @@ namespace odb
vector_impl (const vector_impl&);
#ifdef ODB_CXX11
- vector_impl (vector_impl&&);
+ vector_impl (vector_impl&&) noexcept;
#endif
void
@@ -195,7 +195,7 @@ namespace odb
vector_base (const vector_base&);
#ifdef ODB_CXX11
- vector_base (vector_base&&);
+ vector_base (vector_base&&) noexcept;
#endif
void
diff --git a/odb/vector-impl.ixx b/odb/vector-impl.ixx
index 3377cb8..21999d5 100644
--- a/odb/vector-impl.ixx
+++ b/odb/vector-impl.ixx
@@ -18,9 +18,19 @@ namespace odb
{
}
+ inline void vector_impl::
+ swap (vector_impl& x)
+ {
+ std::swap (state_, x.state_);
+ std::swap (size_, x.size_);
+ std::swap (tail_, x.tail_);
+ std::swap (capacity_, x.capacity_);
+ std::swap (data_, x.data_);
+ }
+
#ifdef ODB_CXX11
inline vector_impl::
- vector_impl (vector_impl&& x)
+ vector_impl (vector_impl&& x) noexcept
: state_ (state_not_tracking),
size_ (0), tail_ (0), capacity_ (0), data_ (0)
{
@@ -36,16 +46,6 @@ namespace odb
}
inline void vector_impl::
- swap (vector_impl& x)
- {
- std::swap (state_, x.state_);
- std::swap (size_, x.size_);
- std::swap (tail_, x.tail_);
- std::swap (capacity_, x.capacity_);
- std::swap (data_, x.data_);
- }
-
- inline void vector_impl::
reserve (std::size_t n)
{
if (n > capacity_)
@@ -146,6 +146,17 @@ namespace odb
inline vector_base::
vector_base (): tran_ (0) {}
+ inline void vector_base::
+ _arm (transaction& t) const
+ {
+ tran_ = &t;
+ t.callback_register (&rollback,
+ const_cast<vector_base*> (this),
+ transaction::event_rollback,
+ 0,
+ &tran_);
+ }
+
inline vector_base::
vector_base (const vector_base& x)
: impl_ (x.impl_), tran_ (0)
@@ -167,12 +178,19 @@ namespace odb
#ifdef ODB_CXX11
inline vector_base::
- vector_base (vector_base&& x)
+ vector_base (vector_base&& x) noexcept
: impl_ (std::move (x.impl_)), tran_ (0)
{
if (x.tran_ != 0)
{
x.tran_->callback_unregister (&x);
+
+ // Note that _arm() can potentially throw bad_alloc while adding a new
+ // callback to the callbacks list of the transaction object. However, we
+ // assume that this will not happen since the new callback should be
+ // saved into an existing slot, freed by the above callback_unregister()
+ // call.
+ //
_arm (*x.tran_);
}
}
@@ -189,15 +207,4 @@ namespace odb
{
return impl_.tracking ();
}
-
- inline void vector_base::
- _arm (transaction& t) const
- {
- tran_ = &t;
- t.callback_register (&rollback,
- const_cast<vector_base*> (this),
- transaction::event_rollback,
- 0,
- &tran_);
- }
}
diff --git a/odb/vector.hxx b/odb/vector.hxx
index ac75ef1..3fe7d8a 100644
--- a/odb/vector.hxx
+++ b/odb/vector.hxx
@@ -91,10 +91,16 @@ namespace odb
{return v_.get_allocator ();}
#ifdef ODB_CXX11
- vector(vector&& x): vector_base (std::move (x)), v_ (std::move (x.v_)) {}
+ vector(vector&& x) noexcept
+ : vector_base (std::move (x)), v_ (std::move (x.v_)) {}
+
vector(const vector& x, const A& a): vector_base (x), v_ (x.v_, a) {}
vector(vector&& x, const A& a)
: vector_base (std::move (x)), v_ (std::move (x.v_), a) {}
+
+ // Note: noexcept is not specified since it can throw while reallocating
+ // impl_.
+ //
vector& operator=(vector&&);
#ifdef ODB_CXX11_INITIALIZER_LIST
vector(std::initializer_list<T> il, const A& a = A()): v_ (il, a) {}
diff --git a/odb/version-build2.hxx.in b/odb/version-build2.hxx.in
index 77a2924..3672585 100644
--- a/odb/version-build2.hxx.in
+++ b/odb/version-build2.hxx.in
@@ -5,7 +5,7 @@
// For the ODB compiler (temporary).
//
-#define ODB_VERSION 20472
+#define ODB_VERSION 20476
// The numeric version format is AAAAABBBBBCCCCCDDDE where:
//
diff --git a/odb/version.hxx b/odb/version.hxx
index c607f92..4961e1a 100644
--- a/odb/version.hxx
+++ b/odb/version.hxx
@@ -29,13 +29,13 @@
// ODB interface version: minor, major, and alpha/beta versions.
//
-#define ODB_VERSION 20472
-#define ODB_VERSION_STR "2.5-b.22"
+#define ODB_VERSION 20476
+#define ODB_VERSION_STR "2.5-b.26"
// libodb version: interface version plus the bugfix version.
//
-#define LIBODB_VERSION 2049972
-#define LIBODB_VERSION_STR "2.5.0-b.22"
+#define LIBODB_VERSION 2049976
+#define LIBODB_VERSION_STR "2.5.0-b.26"
#include <odb/post.hxx>
diff --git a/version b/version
deleted file mode 100644
index 6d2beda..0000000
--- a/version
+++ /dev/null
@@ -1 +0,0 @@
-2.5.0-b.22
diff --git a/version.txt b/version.txt
new file mode 100644
index 0000000..6bc2f39
--- /dev/null
+++ b/version.txt
@@ -0,0 +1 @@
+2.5.0-b.26