add ref-qualifiers to avoid dangling refs/ptrs

This commit is contained in:
Danny Robson 2016-03-17 18:05:28 +11:00
parent 42806d2060
commit ab330cc520
14 changed files with 128 additions and 99 deletions

View File

@ -345,7 +345,7 @@ LDADD = $(top_builddir)/libcruft-util.a $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_L
## Tests ## Tests
AM_LDFLAGS += $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB) AM_LDFLAGS += $(BOOST_LDFLAGS) $(BOOST_FILESYSTEM_LIB) $(BOOST_SYSTEM_LIB)
AM_CXXFLAGS += -I$(top_srcdir) AM_CXXFLAGS += -I$(top_srcdir) -I$(top_builddir)
TEST_BIN = \ TEST_BIN = \
test/alloc/arena \ test/alloc/arena \

View File

@ -49,15 +49,17 @@ namespace util { namespace alloc {
} }
// allocation management // allocation management
void* allocate (size_t bytes, void*
size_t alignment = DEFAULT_ALIGNMENT) allocate (size_t bytes,
size_t alignment = DEFAULT_ALIGNMENT) &
{ {
return m_child->allocate (bytes, alignment); return m_child->allocate (bytes, alignment);
} }
void deallocate (void *ptr, void
size_t bytes, deallocate (void *ptr,
size_t alignment = DEFAULT_ALIGNMENT) size_t bytes,
size_t alignment = DEFAULT_ALIGNMENT)
{ {
return m_child->deallocate (ptr, bytes, alignment); return m_child->deallocate (ptr, bytes, alignment);
} }

View File

@ -68,6 +68,7 @@ namespace util { namespace cmdopt {
class present : public base { class present : public base {
public: public:
explicit present (bool&); explicit present (bool&);
explicit present (bool&&) = delete;
using base::execute; using base::execute;
virtual void execute (void) override; virtual void execute (void) override;
@ -85,15 +86,16 @@ namespace util { namespace cmdopt {
class value : public base { class value : public base {
public: public:
explicit value (T&); explicit value (T&);
explicit value (T&&) = delete;
using base::execute; using base::execute;
void execute (const char *restrict) override; void execute (const char *restrict) override;
const std::string& example (void) const override; const std::string& example (void) const override;
T data (void) const; const T& data (void) const&;
T& data (void); T& data (void) &;
T& data (T); T& data (T) &;
private: private:
T& m_data; T& m_data;
@ -104,6 +106,7 @@ namespace util { namespace cmdopt {
class count : public value<T> { class count : public value<T> {
public: public:
explicit count (T&); explicit count (T&);
explicit count (T&&) = delete;
using value<T>::execute; using value<T>::execute;
void execute (void) override; void execute (void) override;

View File

@ -96,8 +96,8 @@ namespace util { namespace cmdopt {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T const T&
option::value<T>::data (void) const option::value<T>::data (void) const&
{ {
return m_data; return m_data;
} }
@ -106,7 +106,7 @@ namespace util { namespace cmdopt {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T& T&
option::value<T>::data (void) option::value<T>::data (void) &
{ {
return m_data; return m_data;
} }
@ -115,7 +115,7 @@ namespace util { namespace cmdopt {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename T> template <typename T>
T& T&
option::value<T>::data (T _data) option::value<T>::data (T _data) &
{ {
return m_data = _data; return m_data = _data;
} }

View File

@ -273,8 +273,10 @@ namespace util {
typedef R type; typedef R type;
static const std::string name; static const std::string name;
static const R& get (const K &k) { return k.*M; } static const R& get (const K &k) { return k.*M; }
static R get (K &k) { return k.*M; } static R& get ( K &k) { return k.*M; }
static R& get ( K &&) = delete;
}; };
/////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////
@ -377,6 +379,8 @@ namespace util {
std::tuple_element<I, typename type<K>::fields>::type::get (k)... std::tuple_element<I, typename type<K>::fields>::type::get (k)...
); );
} }
static auto make (K&&) = delete;
}; };
} }
@ -389,6 +393,16 @@ namespace util {
{ {
return detail::_as_tuple<K>::make (k); return detail::_as_tuple<K>::make (k);
} }
template <typename K>
auto as_tuple (K &_k)
{
const K &k = _k;
return as_tuple (k);
}
template <typename K>
auto as_tuple (K&&) = delete;
} }
#endif #endif

View File

@ -20,7 +20,9 @@
#include "json/flat.hpp" #include "json/flat.hpp"
#include "json/except.hpp" #include "json/except.hpp"
#include "io.hpp" #include "io.hpp"
#include "debug.hpp"
#include <deque> #include <deque>

View File

@ -222,73 +222,73 @@ json::tree::from_path (const std::string &path)
// Type conversion // Type conversion
const json::tree::object& const json::tree::object&
json::tree::node::as_object (void) const json::tree::node::as_object (void) const&
{ throw json::type_error ("node is not an object"); } { throw json::type_error ("node is not an object"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::array& const json::tree::array&
json::tree::node::as_array (void) const json::tree::node::as_array (void) const&
{ throw json::type_error ("node is not an array"); } { throw json::type_error ("node is not an array"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::string& const json::tree::string&
json::tree::node::as_string (void) const json::tree::node::as_string (void) const&
{ throw json::type_error ("node is not a string"); } { throw json::type_error ("node is not a string"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::number& const json::tree::number&
json::tree::node::as_number (void) const json::tree::node::as_number (void) const&
{ throw json::type_error ("node is not a number"); } { throw json::type_error ("node is not a number"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::boolean& const json::tree::boolean&
json::tree::node::as_boolean (void) const json::tree::node::as_boolean (void) const&
{ throw json::type_error ("node is not a boolean"); } { throw json::type_error ("node is not a boolean"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::null& const json::tree::null&
json::tree::node::as_null (void) const json::tree::node::as_null (void) const&
{ throw json::type_error ("node is not a null"); } { throw json::type_error ("node is not a null"); }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
json::tree::object& json::tree::object&
json::tree::node::as_object (void) json::tree::node::as_object (void)&
{ throw json::type_error ("node is not an object"); } { throw json::type_error ("node is not an object"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::array& json::tree::array&
json::tree::node::as_array (void) json::tree::node::as_array (void)&
{ throw json::type_error ("node is not an array"); } { throw json::type_error ("node is not an array"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::string& json::tree::string&
json::tree::node::as_string (void) json::tree::node::as_string (void)&
{ throw json::type_error ("node is not a string"); } { throw json::type_error ("node is not a string"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::number& json::tree::number&
json::tree::node::as_number (void) json::tree::node::as_number (void)&
{ throw json::type_error ("node is not a number"); } { throw json::type_error ("node is not a number"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::boolean& json::tree::boolean&
json::tree::node::as_boolean (void) json::tree::node::as_boolean (void)&
{ throw json::type_error ("node is not a boolean"); } { throw json::type_error ("node is not a boolean"); }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::null& json::tree::null&
json::tree::node::as_null (void) json::tree::node::as_null (void)&
{ throw json::type_error ("node is not a null"); } { throw json::type_error ("node is not a null"); }
@ -331,7 +331,7 @@ json::tree::node::as_uint (void) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const char* const char*
json::tree::node::as_chars (void) const json::tree::node::as_chars (void) const&
{ {
return as_string ().native ().c_str (); return as_string ().native ().c_str ();
} }
@ -405,25 +405,25 @@ bool json::tree::node::operator==(const char *rhs) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::node& json::tree::node&
json::tree::node::operator[] (const std::string &key) json::tree::node::operator[] (const std::string &key)&
{ return as_object ()[key]; } { return as_object ()[key]; }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::node& json::tree::node&
json::tree::node::operator[] (unsigned int idx) json::tree::node::operator[] (unsigned int idx)&
{ return as_array()[idx]; } { return as_array()[idx]; }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::node& const json::tree::node&
json::tree::node::operator[] (const std::string &key) const json::tree::node::operator[] (const std::string &key) const&
{ return as_object ()[key]; } { return as_object ()[key]; }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::node& const json::tree::node&
json::tree::node::operator[] (unsigned int idx) const json::tree::node::operator[] (unsigned int idx) const&
{ return as_array()[idx]; } { return as_array()[idx]; }
@ -474,7 +474,7 @@ json::tree::object::insert (const std::string &_key, std::unique_ptr<json::tree:
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::node& json::tree::node&
json::tree::object::operator[](const std::string &key) json::tree::object::operator[](const std::string &key)&
{ {
auto value = m_values.find (key); auto value = m_values.find (key);
if (value == m_values.end ()) if (value == m_values.end ())
@ -486,7 +486,7 @@ json::tree::object::operator[](const std::string &key)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::node& const json::tree::node&
json::tree::object::operator[](const std::string &key) const json::tree::object::operator[](const std::string &key) const&
{ {
auto value = m_values.find (key); auto value = m_values.find (key);
if (value == m_values.end ()) if (value == m_values.end ())
@ -634,7 +634,7 @@ json::tree::array::size (void) const
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
json::tree::node& json::tree::node&
json::tree::array::operator[] (unsigned int idx) json::tree::array::operator[] (unsigned int idx)&
{ {
return *m_values[idx]; return *m_values[idx];
} }
@ -642,7 +642,7 @@ json::tree::array::operator[] (unsigned int idx)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
const json::tree::node& const json::tree::node&
json::tree::array::operator[] (unsigned int idx) const json::tree::array::operator[] (unsigned int idx) const&
{ {
return *m_values[idx]; return *m_values[idx];
} }

View File

@ -55,19 +55,19 @@ namespace json { namespace tree {
virtual ~node () { ; } virtual ~node () { ; }
virtual std::unique_ptr<node> clone (void) const = 0; virtual std::unique_ptr<node> clone (void) const = 0;
virtual const object& as_object (void) const; virtual const object& as_object (void) const&;
virtual const array& as_array (void) const; virtual const array& as_array (void) const&;
virtual const string& as_string (void) const; virtual const string& as_string (void) const&;
virtual const number& as_number (void) const; virtual const number& as_number (void) const&;
virtual const boolean& as_boolean (void) const; virtual const boolean& as_boolean (void) const&;
virtual const null& as_null (void) const; virtual const null& as_null (void) const&;
virtual object& as_object (void); virtual object& as_object (void)&;
virtual array& as_array (void); virtual array& as_array (void)&;
virtual string& as_string (void); virtual string& as_string (void)&;
virtual number& as_number (void); virtual number& as_number (void)&;
virtual boolean& as_boolean (void); virtual boolean& as_boolean (void)&;
virtual null& as_null (void); virtual null& as_null (void)&;
// we don't provide operators for conversion due to ambiguities // we don't provide operators for conversion due to ambiguities
// introduced when using indexing operators with pointer // introduced when using indexing operators with pointer
@ -76,7 +76,7 @@ namespace json { namespace tree {
virtual float as_float (void) const; virtual float as_float (void) const;
virtual double as_double (void) const; virtual double as_double (void) const;
virtual size_t as_uint (void) const; virtual size_t as_uint (void) const;
virtual const char* as_chars (void) const; virtual const char* as_chars (void) const&;
template <typename T> template <typename T>
T as (void) const; T as (void) const;
@ -102,10 +102,10 @@ namespace json { namespace tree {
virtual bool operator==(const char *rhs) const; virtual bool operator==(const char *rhs) const;
virtual bool operator!=(const char *rhs) const { return !(*this == rhs); } virtual bool operator!=(const char *rhs) const { return !(*this == rhs); }
virtual node& operator[] (const std::string&); virtual node& operator[] (const std::string&)&;
virtual node& operator[] (unsigned int); virtual node& operator[] (unsigned int)&;
virtual const node& operator[] (const std::string&) const; virtual const node& operator[] (const std::string&) const&;
virtual const node& operator[] (unsigned int) const; virtual const node& operator[] (unsigned int) const&;
virtual std::ostream& write (std::ostream &os) const = 0; virtual std::ostream& write (std::ostream &os) const = 0;
}; };
@ -126,9 +126,9 @@ namespace json { namespace tree {
virtual ~object (); virtual ~object ();
virtual std::unique_ptr<node> clone (void) const override; virtual std::unique_ptr<node> clone (void) const override;
virtual const object& as_object (void) const override { return *this; } virtual const object& as_object (void) const& override { return *this; }
virtual object& as_object (void) override { return *this; } virtual object& as_object (void) & override { return *this; }
virtual bool is_object (void) const override { return true; } virtual bool is_object (void) const override { return true; }
virtual type_t type (void) const override { return OBJECT; } virtual type_t type (void) const override { return OBJECT; }
virtual bool operator==(const object &rhs) const override; virtual bool operator==(const object &rhs) const override;
@ -136,8 +136,8 @@ namespace json { namespace tree {
{ return rhs == *this; } { return rhs == *this; }
virtual void insert (const std::string &key, std::unique_ptr<node>&& value); virtual void insert (const std::string &key, std::unique_ptr<node>&& value);
virtual const node& operator[](const std::string &key) const override; virtual const node& operator[](const std::string &key) const& override;
virtual node& operator[](const std::string &key) override; virtual node& operator[](const std::string &key)& override;
virtual bool has (const std::string&) const; virtual bool has (const std::string&) const;
virtual const_iterator find (const std::string&) const; virtual const_iterator find (const std::string&) const;
@ -173,17 +173,17 @@ namespace json { namespace tree {
virtual ~array(); virtual ~array();
virtual std::unique_ptr<node> clone (void) const override; virtual std::unique_ptr<node> clone (void) const override;
virtual const array& as_array (void) const override { return *this; } virtual const array& as_array (void) const& override { return *this; }
virtual array& as_array (void) override { return *this; } virtual array& as_array (void) & override { return *this; }
virtual bool is_array (void) const override { return true; } virtual bool is_array (void) const override { return true; }
virtual type_t type (void) const override { return ARRAY; } virtual type_t type (void) const override { return ARRAY; }
virtual bool operator==(const array &rhs) const override; virtual bool operator==(const array &rhs) const override;
virtual bool operator==(const node &rhs) const override; virtual bool operator==(const node &rhs) const override;
virtual size_t size (void) const; virtual size_t size (void) const;
virtual node& operator [](unsigned int idx) override; virtual node& operator [](unsigned int idx)& override;
virtual const node& operator [](unsigned int idx) const override; virtual const node& operator [](unsigned int idx) const& override;
virtual iterator begin (void); virtual iterator begin (void);
virtual iterator end (void); virtual iterator end (void);
@ -209,9 +209,9 @@ namespace json { namespace tree {
string (const char *_first, const char *_last): m_value (_first, _last) { ; } string (const char *_first, const char *_last): m_value (_first, _last) { ; }
virtual std::unique_ptr<node> clone (void) const override; virtual std::unique_ptr<node> clone (void) const override;
virtual const string& as_string (void) const override { return *this; } virtual const string& as_string (void) const& override { return *this; }
virtual string& as_string (void) override { return *this; } virtual string& as_string (void) & override { return *this; }
virtual bool is_string (void) const override { return true; } virtual bool is_string (void) const override { return true; }
virtual type_t type (void) const override { return STRING; } virtual type_t type (void) const override { return STRING; }
@ -243,9 +243,9 @@ namespace json { namespace tree {
explicit number (size_t _value): m_value (_value) { ; } explicit number (size_t _value): m_value (_value) { ; }
virtual std::unique_ptr<node> clone (void) const override; virtual std::unique_ptr<node> clone (void) const override;
virtual const number& as_number (void) const override { return *this; } virtual const number& as_number (void) const& override { return *this; }
virtual number& as_number (void) override { return *this; } virtual number& as_number (void) & override { return *this; }
virtual bool is_number (void) const override { return true; } virtual bool is_number (void) const override { return true; }
virtual type_t type (void) const override { return NUMBER; } virtual type_t type (void) const override { return NUMBER; }
@ -269,9 +269,9 @@ namespace json { namespace tree {
explicit boolean (bool _value): m_value (_value) { ; } explicit boolean (bool _value): m_value (_value) { ; }
virtual std::unique_ptr<node> clone (void) const override; virtual std::unique_ptr<node> clone (void) const override;
virtual const boolean& as_boolean (void) const override { return *this; } virtual const boolean& as_boolean (void) const& override { return *this; }
virtual boolean& as_boolean (void) override { return *this; } virtual boolean& as_boolean (void) & override { return *this; }
virtual bool is_boolean (void) const override { return true; } virtual bool is_boolean (void) const override { return true; }
virtual type_t type (void) const override { return BOOLEAN; } virtual type_t type (void) const override { return BOOLEAN; }
@ -296,9 +296,9 @@ namespace json { namespace tree {
virtual bool operator==(const node &rhs) const override virtual bool operator==(const node &rhs) const override
{ return rhs == *this; } { return rhs == *this; }
virtual bool is_null (void) const override { return true; } virtual const null& as_null (void) const& override { return *this; }
virtual const null& as_null (void) const override { return *this; } virtual null& as_null (void) & override { return *this; }
virtual null& as_null (void) override { return *this; } virtual bool is_null (void) const override { return true; }
virtual std::ostream& write (std::ostream &os) const override; virtual std::ostream& write (std::ostream &os) const override;
}; };
@ -319,13 +319,21 @@ namespace json { namespace tree {
} } } }
template <typename T, class ...Args> template <typename T, class ...Args>
std::unique_ptr<json::tree::node> to_json (const T &t, Args&&... args) { std::unique_ptr<json::tree::node>
return json::tree::io<T>::serialise (t, std::forward<Args>(args)...); to_json (const T &t, Args&&... args)
{
return json::tree::io<T>::serialise (
t, std::forward<Args>(args)...
);
} }
template <typename T, class ...Args> template <typename T, class ...Args>
T from_json (const json::tree::node &n, Args&&... args) { T
return json::tree::io<T>::deserialise (n, std::forward<Args>(args)...); from_json (const json::tree::node &n, Args&&... args)
{
return json::tree::io<T>::deserialise (
n, std::forward<Args>(args)...
);
} }
#endif #endif

View File

@ -124,7 +124,7 @@ circular::~circular ()
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
char* char*
circular::begin (void) circular::begin (void)&
{ {
return m_begin; return m_begin;
} }
@ -132,7 +132,7 @@ circular::begin (void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
char* char*
circular::end (void) circular::end (void)&
{ {
return m_end; return m_end;
} }

View File

@ -35,14 +35,14 @@ namespace util { namespace memory { namespace buffer {
circular& operator= (const circular&) = delete; circular& operator= (const circular&) = delete;
circular& operator= (circular&&) = delete; circular& operator= (circular&&) = delete;
char& operator[] (size_t); char& operator[] (size_t)&;
const char& operator[] (size_t) const; const char& operator[] (size_t) const&;
char* begin (void); char* begin (void)&;
char* end (void); char* end (void)&;
const char* begin (void) const; const char* begin (void) const&;
const char* end (void) const; const char* end (void) const&;
size_t size (void) const; size_t size (void) const;

View File

@ -64,7 +64,7 @@ paged::~paged ()
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
char* char*
paged::begin (void) paged::begin (void)&
{ {
return m_begin; return m_begin;
} }
@ -72,7 +72,7 @@ paged::begin (void)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
char* char*
paged::end (void) paged::end (void)&
{ {
return m_end; return m_end;
} }

View File

@ -32,14 +32,14 @@ namespace util { namespace memory { namespace buffer {
paged& operator= (const paged&) = delete; paged& operator= (const paged&) = delete;
paged& operator= (paged &&) = delete; paged& operator= (paged &&) = delete;
char* begin (void); char* begin (void)&;
char* end (void); char* end (void)&;
const char* cbegin (void); const char* cbegin (void)&;
const char* cend (void); const char* cend (void)&;
const char* begin (void) const; const char* begin (void) const&;
const char* end (void) const; const char* end (void) const&;
void access (char*); void access (char*);

View File

@ -57,8 +57,8 @@ namespace util {
// Indexing // Indexing
size_t index (const T*) const; size_t index (const T*) const;
T& operator[] (size_t idx); T& operator[] (size_t idx) &;
const T& operator[] (size_t idx) const; const T& operator[] (size_t idx) const&;
}; };
} }

View File

@ -52,13 +52,13 @@ namespace util {
{ data = rhs.data; return *this; } { data = rhs.data; return *this; }
// simple value_type assignment. // simple value_type assignment.
strongdef& operator= (const T &rhs) strongdef& operator= (const T &rhs)&
{ data = rhs; return *this; } { data = rhs; return *this; }
// conversion operators must not be explicit or it defeats the point // conversion operators must not be explicit or it defeats the point
// of this class (ease of use, transparency). // of this class (ease of use, transparency).
operator const T& (void) const { return data; } operator const T& (void) const& { return data; }
operator T& (void) { return data; } operator T& (void) & { return data; }
// explicitly disable equality with unequal types or tags. this // explicitly disable equality with unequal types or tags. this
// prevents the conversion operator getting invoked and falsely // prevents the conversion operator getting invoked and falsely