decommission the safe-bool-idiom (closes #477)
obsoleted by C++11 * in most cases, it can be replaced by an explicit conversion operator * especially for the Lumiera Forward Iterators, we need an implicit conversion
This commit is contained in:
parent
9c21164ae6
commit
afe07bdb16
36 changed files with 114 additions and 382 deletions
|
|
@ -1043,7 +1043,6 @@ Items not used propagate towards the tail where they will be reused.
|
|||
//access-casted.hpp
|
||||
//advice.hpp symbol-impl.cpp
|
||||
//allocationcluster.cpp symbol.hpp
|
||||
//bool-checkable.hpp
|
||||
//cmdline.cpp
|
||||
//cmdline.hpp
|
||||
//del-stash.hpp
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "include/logging.h"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/result.hpp"
|
||||
|
||||
extern "C" {
|
||||
|
|
@ -257,8 +256,7 @@ namespace backend {
|
|||
* to join on the termination of this thread.
|
||||
*/
|
||||
class ThreadJoinable
|
||||
: public lib::BoolCheckable<ThreadJoinable
|
||||
,Thread> // baseclass
|
||||
: public Thread
|
||||
{
|
||||
public:
|
||||
ThreadJoinable (Literal purpose, Operation const& operation,
|
||||
|
|
|
|||
|
|
@ -75,7 +75,6 @@
|
|||
#define LUMIERA_QUERY_H
|
||||
|
||||
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/typed-counter.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "lib/query-text.hpp"
|
||||
|
|
@ -162,7 +161,6 @@ namespace lumiera {
|
|||
* @see Resolution
|
||||
*/
|
||||
class Result
|
||||
: public lib::BoolCheckable<Result>
|
||||
{
|
||||
void* cur_;
|
||||
|
||||
|
|
@ -178,7 +176,8 @@ namespace lumiera {
|
|||
}
|
||||
|
||||
public:
|
||||
bool isValid() const { return bool(cur_); }
|
||||
explicit operator bool() const { return isValid(); }
|
||||
bool isValid() const { return bool(cur_); }
|
||||
|
||||
Result() : cur_(0) { } ///< create an NIL result
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,142 +0,0 @@
|
|||
/*
|
||||
BOOL-CHECKABLE.hpp - mixin template for defining a safe conversion to bool
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
/** @file bool-checkable.hpp
|
||||
** Mix-in for implicit conversion to bool.
|
||||
** When inheriting from BoolCheckable, a class becomes convertible
|
||||
** to `bool` -- which is implemented by invoking an operation `isValid()`
|
||||
** on this class.
|
||||
**
|
||||
** @deprecated 2016 it is not clear if we'll retain that feature on the long run.
|
||||
** Essentially this was needed to work around the dangers of implicit `bool`
|
||||
** conversion in C++98, which is largely obsolete since C++11, because the
|
||||
** rectified semantics of implicit conversion now prevent most unexpected
|
||||
** usages of this conversion function, like e.g. in comparison operators
|
||||
** on a derived class. Moreover, fun fact is, the implementation in this
|
||||
** header is not even correct, see Ticket #477
|
||||
** On the other hand, the basic idea of exposing a `isValid()` function
|
||||
** does not sound too bad...
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#ifndef LIB_BOOL_CHECKABLE_H
|
||||
#define LIB_BOOL_CHECKABLE_H
|
||||
|
||||
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace lib {
|
||||
|
||||
namespace imp {
|
||||
struct Dummy {};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Provide an implicit conversion to "bool".
|
||||
* Inherit (mix-in) from this template by providing the
|
||||
* concrete subclass type ("CRTP"). Additionally, to implement
|
||||
* the specific logic of this bool check, the subclass using this
|
||||
* template must provide a public function \c isValid()
|
||||
*
|
||||
* \par safe bool conversion
|
||||
* Generally speaking, a direct automatic conversion to bool would be
|
||||
* a dangerous feature, because bool is considered an "integral type" in C.
|
||||
* Thus, you'd not only get the ability to write very expressive checks
|
||||
* like \c if(object) -- you would also get automatic conversions to int
|
||||
* where you'd never expect them. In C++ there is a well-known idiom to
|
||||
* circumvent this problem. Unfortunately, this idiom isn't easy to
|
||||
* grasp, involving the convoluted syntax of member pointers.
|
||||
* So we try to hide away these details into a mixin.
|
||||
*
|
||||
* The idea this implementation is based on is the fact that a
|
||||
* pointer-to-member is "somewhat a pointer" but not \em really a pointer.
|
||||
* Similar to a pointer, a member pointer can be \em unbound, and this
|
||||
* is the property we exploit here. But implementation-wise, a member pointer
|
||||
* is a type information plus an offset into this type, and thus can't be
|
||||
* converted to an integral type. Thus, depending on the result of the
|
||||
* \c isValid() function, the conversion operator returns either a
|
||||
* bound or unbound member pointer.
|
||||
*
|
||||
* @see bool-checkable-test.cpp
|
||||
* @see control::Mutation usage example
|
||||
*/
|
||||
template< class T ///< the target type implementing \c isValid()
|
||||
, class PAR = imp::Dummy ///< optional parent for inheritance chain
|
||||
>
|
||||
struct BoolCheckable
|
||||
: PAR
|
||||
{
|
||||
typedef bool (T::*ValidityCheck)() const;
|
||||
typedef ValidityCheck _unspecified_bool_type;
|
||||
|
||||
/** implicit conversion to "bool" */
|
||||
operator _unspecified_bool_type() const ///< never throws
|
||||
{
|
||||
ValidityCheck isValid (&T::isValid);
|
||||
T const& obj = static_cast<T const&> (*this);
|
||||
|
||||
return (obj.*isValid)()? isValid : 0;
|
||||
}
|
||||
|
||||
bool operator! () const ///< never throws
|
||||
{
|
||||
ValidityCheck isValid (&T::isValid);
|
||||
T const& obj = static_cast<T const&> (*this);
|
||||
|
||||
return not (obj.*isValid)();
|
||||
}
|
||||
|
||||
|
||||
/** safety guard: when this comparison kicks in, the compiler
|
||||
* is about to use an implicit bool conversion on both sides to
|
||||
* perform an equality test. This is most likely not what you want.
|
||||
* Define an explicit equality comparison in the class using BoolCheckable!
|
||||
*/
|
||||
friend bool
|
||||
operator== (BoolCheckable const&, BoolCheckable const&)
|
||||
{
|
||||
BOOST_STATIC_ASSERT (false && sizeof(T) );
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
///////////////////////////////////////TICKET #477 : consider alternative safe-bool idiom
|
||||
// struct _Hidden_type
|
||||
// {
|
||||
// _Hidden_type* _M_bool;
|
||||
// };
|
||||
//
|
||||
// /// This typedef is used to implement the safe_bool idiom.
|
||||
// typedef _Hidden_type* _Hidden_type::* _Safe_bool;
|
||||
//
|
||||
// public:
|
||||
// operator _Safe_bool() const
|
||||
// {
|
||||
// return isValid()? &_Hidden_type::_M_bool : 0; }
|
||||
|
||||
|
||||
} // namespace lib
|
||||
#endif
|
||||
|
|
@ -85,7 +85,6 @@ namespace lib {
|
|||
*/
|
||||
template<class IT>
|
||||
class PtrDerefIter
|
||||
: public lib::BoolCheckable<PtrDerefIter<IT>>
|
||||
{
|
||||
IT i_; ///< nested source iterator
|
||||
|
||||
|
|
@ -142,6 +141,9 @@ namespace lib {
|
|||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
|
||||
/** explicit builder to allow creating a const variant from the basic srcIter type.
|
||||
* Again, the reason necessitating this "backdoor" is that we want to swallow one level
|
||||
|
|
@ -230,7 +232,6 @@ namespace lib {
|
|||
*/
|
||||
template<class IT>
|
||||
class AddressExposingIter
|
||||
: public lib::BoolCheckable<AddressExposingIter<IT>>
|
||||
{
|
||||
typedef typename IT::pointer _Ptr;
|
||||
|
||||
|
|
@ -265,6 +266,7 @@ namespace lib {
|
|||
takeAddress();
|
||||
}
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -55,7 +55,6 @@ namespace iter_stl {
|
|||
*/
|
||||
template<typename IT>
|
||||
class DistinctIter
|
||||
: public lib::BoolCheckable<DistinctIter<IT>>
|
||||
{
|
||||
public:
|
||||
typedef typename IT::value_type value_type;
|
||||
|
|
@ -72,9 +71,11 @@ namespace iter_stl {
|
|||
DistinctIter() : i_(), prev_() { }
|
||||
DistinctIter(IT const& i) : i_(i),prev_() { memorise(); }
|
||||
|
||||
pointer operator->() const { return i_; }
|
||||
reference operator*() const { return *i_; }
|
||||
bool isValid() const { return i_; }
|
||||
pointer operator->() const { return i_; }
|
||||
reference operator*() const { return *i_;}
|
||||
bool isValid() const { return i_; }
|
||||
|
||||
operator bool() const { return i_; }
|
||||
|
||||
|
||||
DistinctIter&
|
||||
|
|
@ -415,7 +416,6 @@ namespace iter_stl {
|
|||
*/
|
||||
template<typename VAL>
|
||||
class IterSnapshot
|
||||
: public lib::BoolCheckable<IterSnapshot<VAL>>
|
||||
{
|
||||
typedef std::vector<VAL> Sequence;
|
||||
|
||||
|
|
@ -456,6 +456,8 @@ namespace iter_stl {
|
|||
buffer_.push_back(*p);
|
||||
}
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
|
|
|||
|
|
@ -99,7 +99,6 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/iter-type-binding.hpp"
|
||||
|
||||
|
||||
|
|
@ -157,7 +156,6 @@ namespace lib {
|
|||
*/
|
||||
template<class POS, class CON>
|
||||
class IterAdapter
|
||||
: public lib::BoolCheckable<IterAdapter<POS,CON>>
|
||||
{
|
||||
CON source_;
|
||||
mutable POS pos_;
|
||||
|
|
@ -179,6 +177,8 @@ namespace lib {
|
|||
, pos_()
|
||||
{ }
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
||||
|
|
@ -298,7 +298,6 @@ namespace lib {
|
|||
*/
|
||||
template<typename T, class ST =T>
|
||||
class IterStateWrapper
|
||||
: public lib::BoolCheckable<IterStateWrapper<T,ST>>
|
||||
{
|
||||
ST core_;
|
||||
|
||||
|
|
@ -323,6 +322,8 @@ namespace lib {
|
|||
: core_()
|
||||
{ }
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
||||
|
|
@ -422,7 +423,6 @@ namespace lib {
|
|||
*/
|
||||
template<class IT>
|
||||
class RangeIter
|
||||
: public lib::BoolCheckable<RangeIter<IT>>
|
||||
{
|
||||
IT p_;
|
||||
IT e_;
|
||||
|
|
@ -452,6 +452,8 @@ namespace lib {
|
|||
, e_(oIter.getEnd())
|
||||
{ }
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
||||
|
|
@ -531,7 +533,6 @@ namespace lib {
|
|||
*/
|
||||
template<typename INT>
|
||||
class NumIter
|
||||
: public lib::BoolCheckable<NumIter<INT>>
|
||||
{
|
||||
INT i_;
|
||||
INT e_;
|
||||
|
|
@ -559,6 +560,8 @@ namespace lib {
|
|||
|
||||
// standard copy operations acceptable
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
|
@ -677,7 +680,6 @@ namespace lib {
|
|||
/** wrapper to declare exposed values const */
|
||||
template<class IT>
|
||||
class ConstIter
|
||||
: public lib::BoolCheckable<ConstIter<IT>>
|
||||
{
|
||||
IT i_; ///< nested source iterator
|
||||
|
||||
|
|
@ -691,6 +693,7 @@ namespace lib {
|
|||
: i_(srcIter)
|
||||
{ }
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@
|
|||
#define LIB_ITERTOOLS_H
|
||||
|
||||
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/trait.hpp"
|
||||
|
|
@ -147,7 +146,6 @@ namespace lib {
|
|||
*/
|
||||
template<class CORE>
|
||||
class IterTool
|
||||
: public lib::BoolCheckable<IterTool<CORE>>
|
||||
{
|
||||
|
||||
protected: /* == iteration control == */
|
||||
|
|
@ -167,7 +165,8 @@ namespace lib {
|
|||
|
||||
do core_.advance();
|
||||
while (core_.pipe() && !core_.evaluate());
|
||||
return core_.pipe();
|
||||
|
||||
return bool{core_.pipe()};
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -191,6 +190,8 @@ namespace lib {
|
|||
hasData();
|
||||
}
|
||||
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
|
||||
/* === lumiera forward iterator concept === */
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@
|
|||
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/opaque-holder.hpp"
|
||||
#include "lib/functor-util.hpp"
|
||||
|
||||
|
|
@ -199,7 +198,6 @@ namespace meta{
|
|||
* and to retrieve it without overhead, but also without safety.
|
||||
*/
|
||||
class StoreUncheckedFunPtr
|
||||
: public lib::BoolCheckable<StoreUncheckedFunPtr>
|
||||
{
|
||||
void *funP_;
|
||||
|
||||
|
|
@ -223,11 +221,8 @@ namespace meta{
|
|||
}
|
||||
|
||||
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return funP_;
|
||||
}
|
||||
explicit operator bool() const { return funP_; }
|
||||
bool isValid() const { return funP_; }
|
||||
|
||||
friend bool
|
||||
operator== (StoreUncheckedFunPtr const& o1,
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/access-casted.hpp"
|
||||
#include "lib/util.hpp"
|
||||
|
||||
|
|
@ -192,7 +191,6 @@ namespace lib {
|
|||
///< how to access the contents via a common interface?
|
||||
>
|
||||
class InPlaceAnyHolder
|
||||
: public BoolCheckable<InPlaceAnyHolder<siz, AccessPolicy>>
|
||||
{
|
||||
typedef typename AccessPolicy::Base * BaseP;
|
||||
|
||||
|
|
@ -475,6 +473,12 @@ namespace lib {
|
|||
{
|
||||
return buff().isValid();
|
||||
}
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@
|
|||
#define LIB_OPTIONAL_REF_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
|
||||
namespace lib {
|
||||
|
|
@ -60,7 +59,6 @@ namespace lib {
|
|||
*/
|
||||
template<typename T>
|
||||
class OptionalRef
|
||||
: public lib::BoolCheckable<OptionalRef<T>>
|
||||
{
|
||||
T* ref_;
|
||||
|
||||
|
|
@ -82,6 +80,9 @@ namespace lib {
|
|||
: ref_(&target)
|
||||
{ }
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
T&
|
||||
operator() () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -146,10 +146,9 @@ namespace lib {
|
|||
char content_[sizeof(TY)];
|
||||
char created_;
|
||||
|
||||
typedef ScopedHolder<TY> _ThisType; ////TODO can get rid of this typedef, after using BoolCheckable
|
||||
|
||||
|
||||
static char must_be_empty (_ThisType const& ref)
|
||||
static char
|
||||
must_be_empty (ScopedHolder<TY> const& ref)
|
||||
{
|
||||
if (ref)
|
||||
throw lumiera::error::Logic("ScopedHolder protocol violation: "
|
||||
|
|
@ -225,16 +224,9 @@ namespace lib {
|
|||
}
|
||||
|
||||
|
||||
typedef char _ThisType::*unspecified_bool_type;
|
||||
|
||||
//////////////////////////////////TICKET #178
|
||||
/** implicit conversion to "bool" */
|
||||
operator unspecified_bool_type() const // never throws
|
||||
{
|
||||
return created_? &_ThisType::created_ : 0;
|
||||
}
|
||||
|
||||
bool operator! () const { return not created_; }
|
||||
explicit operator bool() const { return created_; }
|
||||
bool operator! () const { return not created_; }
|
||||
|
||||
|
||||
friend void
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@
|
|||
#define COMMON_SEARCHPATH_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
|
@ -75,8 +74,7 @@ namespace lib {
|
|||
* @note #next picks the current component and advances the iteration.
|
||||
*/
|
||||
class SearchPathSplitter
|
||||
: public BoolCheckable<SearchPathSplitter
|
||||
, boost::noncopyable>
|
||||
: boost::noncopyable
|
||||
{
|
||||
string pathSpec_;
|
||||
sregex_iterator pos_,
|
||||
|
|
@ -91,6 +89,8 @@ namespace lib {
|
|||
, end_()
|
||||
{ }
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -42,7 +42,6 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
|
|
@ -57,8 +56,7 @@ namespace lib {
|
|||
*/
|
||||
template<class TY>
|
||||
class AccessAsReference
|
||||
: public lib::BoolCheckable<AccessAsReference<TY>
|
||||
, boost::noncopyable>
|
||||
: boost::noncopyable
|
||||
{
|
||||
TY* obj_;
|
||||
|
||||
|
|
@ -87,8 +85,8 @@ namespace lib {
|
|||
return obj_;
|
||||
}
|
||||
|
||||
|
||||
bool isValid() const { return obj_; }
|
||||
explicit operator bool() const { return obj_; }
|
||||
bool isValid() const { return obj_; }
|
||||
};
|
||||
|
||||
} // namespace Singleton
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <pthread.h>
|
||||
|
|
@ -55,8 +54,7 @@ namespace lib {
|
|||
*/
|
||||
template<typename TAR>
|
||||
class ThreadLocalPtr
|
||||
: public BoolCheckable< ThreadLocalPtr<TAR>
|
||||
, boost::noncopyable >
|
||||
: boost::noncopyable
|
||||
{
|
||||
pthread_key_t key_;
|
||||
|
||||
|
|
@ -72,6 +70,8 @@ namespace lib {
|
|||
WARN_IF (pthread_key_delete (key_), sync, "failure to drop thread-local data key");
|
||||
}
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
bool isValid() const { return get(); }
|
||||
TAR& operator* () const { return *accessChecked(); }
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@
|
|||
#define LIB_WRAPPER_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/meta/util.hpp"
|
||||
|
|
@ -139,7 +138,6 @@ namespace wrapper {
|
|||
*/
|
||||
template<typename TY>
|
||||
class ItemWrapper
|
||||
: public BoolCheckable<ItemWrapper<TY>>
|
||||
{
|
||||
|
||||
using TY_unconst = typename meta::UnConst<TY>::Type ;
|
||||
|
|
@ -227,6 +225,11 @@ namespace wrapper {
|
|||
return *this;
|
||||
}
|
||||
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
|
||||
/* == value access == */
|
||||
TY&
|
||||
|
|
@ -259,7 +262,6 @@ namespace wrapper {
|
|||
*/
|
||||
template<typename TY>
|
||||
class ItemWrapper<TY &>
|
||||
: public BoolCheckable<ItemWrapper<TY &> >
|
||||
{
|
||||
|
||||
TY * content_;
|
||||
|
|
@ -275,10 +277,12 @@ namespace wrapper {
|
|||
: content_( &o )
|
||||
{ }
|
||||
|
||||
// using default copy and assignment
|
||||
|
||||
/* using default copy and assignment */
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
/** allowing to re-bind the reference */
|
||||
|
||||
/** allow to re-bind the reference */
|
||||
ItemWrapper&
|
||||
operator= (TY& otherRef)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -68,7 +68,6 @@
|
|||
#ifndef CONTROL_COMMAND_CLOSURE_H
|
||||
#define CONTROL_COMMAND_CLOSURE_H
|
||||
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/meta/function-erasure.hpp"
|
||||
#include "proc/control/argument-erasure.hpp"
|
||||
#include "lib/diff/gen-node.hpp"
|
||||
|
|
@ -105,10 +104,10 @@ namespace control {
|
|||
|
||||
/** Interface */
|
||||
class CmdClosure
|
||||
: public lib::BoolCheckable<CmdClosure>
|
||||
{
|
||||
public:
|
||||
virtual ~CmdClosure() {}
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
virtual operator string() const =0;
|
||||
virtual bool isValid () const =0; ///< does this closure hold a valid argument tuple?
|
||||
|
|
|
|||
|
|
@ -62,7 +62,6 @@
|
|||
#include "proc/control/command-signature.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "proc/control/argument-tuple-accept.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/typelist.hpp"
|
||||
#include "lib/meta/typelist-manip.hpp"
|
||||
|
|
@ -260,7 +259,7 @@ namespace control {
|
|||
|
||||
|
||||
/**
|
||||
* Helper class used solely for \em defining a Command-Object.
|
||||
* Helper class used solely for _defining_ a Command-Object.
|
||||
* This technique is known as "fluent API", see http://en.wikipedia.org/wiki/Fluent_interface
|
||||
* The basic idea is for the user to create a disposable instance of this definition helper,
|
||||
* only for calling a chain of definition functions, which internally build the actual Command object.
|
||||
|
|
@ -277,8 +276,7 @@ namespace control {
|
|||
*
|
||||
*/
|
||||
class CommandDef
|
||||
: public lib::BoolCheckable<CommandDef
|
||||
, boost::noncopyable >
|
||||
: boost::noncopyable
|
||||
{
|
||||
Symbol id_;
|
||||
Command prototype_;
|
||||
|
|
@ -311,6 +309,8 @@ namespace control {
|
|||
}
|
||||
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
bool isValid() const;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,6 @@
|
|||
#include "proc/control/command.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
#include "proc/control/command-mutation.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/format-string.hpp"
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
|
@ -78,9 +77,7 @@ namespace control {
|
|||
* @see Mutation
|
||||
*/
|
||||
class CommandImpl
|
||||
: public lib::BoolCheckable<CommandImpl
|
||||
, boost::noncopyable
|
||||
>
|
||||
: boost::noncopyable
|
||||
{
|
||||
Mutation do_;
|
||||
UndoMutation undo_;
|
||||
|
|
@ -146,6 +143,8 @@ namespace control {
|
|||
, defaultPatt_(orig.defaultPatt_)
|
||||
{ }
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
/** assist with building a clone copy of this CommandImpl.
|
||||
* By accepting the clone builder as a visitor and dispatching
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
#define CONTROL_COMMAND_MUTATION_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "proc/control/command-closure.hpp"
|
||||
#include "proc/control/memento-tie.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@
|
|||
#ifndef CONTROL_COMMAND_OP_CLOSURE_H
|
||||
#define CONTROL_COMMAND_OP_CLOSURE_H
|
||||
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/meta/function.hpp"
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
|
|
|
|||
|
|
@ -59,7 +59,6 @@
|
|||
#include "proc/control/argument-tuple-accept.hpp"
|
||||
#include "proc/control/handling-pattern.hpp"
|
||||
#include "lib/meta/tuple-helper.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/diff/gen-node.hpp"
|
||||
#include "lib/handle.hpp"
|
||||
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@
|
|||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/symbol.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
|
|
@ -70,13 +69,13 @@ namespace control {
|
|||
* @todo couldn't that be replaced by a lib::Result<void> instance??
|
||||
*/
|
||||
class ExecResult
|
||||
: public lib::BoolCheckable<ExecResult>
|
||||
{
|
||||
const string log_;
|
||||
|
||||
public:
|
||||
bool isValid() const;
|
||||
void maybeThrow() const;
|
||||
operator bool() const { return isValid(); }
|
||||
|
||||
protected:
|
||||
ExecResult () { } ///< default: command executed successfully
|
||||
|
|
@ -95,7 +94,6 @@ namespace control {
|
|||
* asynchronously in a background thread.
|
||||
*/
|
||||
class HandlingPattern
|
||||
: public lib::BoolCheckable<HandlingPattern>
|
||||
{
|
||||
public:
|
||||
virtual ~HandlingPattern() {} ///< this is an interface
|
||||
|
|
@ -125,8 +123,8 @@ namespace control {
|
|||
/** likewise invoke the configured UNDO operation */
|
||||
ExecResult undo (CommandImpl& command, string) const;
|
||||
|
||||
|
||||
virtual bool isValid() const =0;
|
||||
explicit operator bool() const { return isValid(); }
|
||||
virtual bool isValid() const =0;
|
||||
|
||||
protected:
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@
|
|||
#ifndef CONTROL_MEMENTO_TIE_H
|
||||
#define CONTROL_MEMENTO_TIE_H
|
||||
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/meta/maybe-compare.hpp"
|
||||
#include "lib/meta/function-closure.hpp"
|
||||
#include "proc/control/command-signature.hpp"
|
||||
|
|
@ -89,9 +88,7 @@ namespace control {
|
|||
*/
|
||||
template<typename SIG, typename MEM>
|
||||
class MementoTie
|
||||
: public lib::BoolCheckable<MementoTie<SIG,MEM>,
|
||||
equality_comparable<MementoTie<SIG,MEM>
|
||||
> >
|
||||
: public equality_comparable<MementoTie<SIG,MEM>>
|
||||
{
|
||||
typedef typename CommandSignature<SIG,MEM>::CaptureSig SIG_cap;
|
||||
typedef typename CommandSignature<SIG,MEM>::UndoOp_Sig SIG_undo;
|
||||
|
|
@ -180,6 +177,12 @@ namespace control {
|
|||
* if all functions are usable and
|
||||
* memento state has been captured
|
||||
*/
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
bool
|
||||
isValid () const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "lib/hash-value.h"
|
||||
#include "proc/streamtype.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
|
||||
namespace proc {
|
||||
|
|
@ -110,7 +109,6 @@ namespace engine {
|
|||
* The real buffer pointer can be retrieved by dereferencing this smart-handle class.
|
||||
*/
|
||||
class BuffHandle
|
||||
: public lib::BoolCheckable<BuffHandle>
|
||||
{
|
||||
typedef StreamType::ImplFacade::DataBuffer Buff;
|
||||
|
||||
|
|
@ -130,6 +128,7 @@ namespace engine {
|
|||
|
||||
// using standard copy operations
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
void emit();
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "lib/hash-value.h"
|
||||
#include "proc/streamtype.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
|
||||
namespace proc {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@
|
|||
#include "lib/error.hpp"
|
||||
#include "include/logging.h"
|
||||
//#include "lib/meta/function.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/scoped-ptrvect.hpp"
|
||||
#include "lib/scoped-holder.hpp"
|
||||
#include "lib/util-foreach.hpp"
|
||||
|
|
@ -106,7 +105,6 @@ namespace engine {
|
|||
* later investigation and diagnostics.
|
||||
*/
|
||||
class BlockPool
|
||||
: public lib::BoolCheckable<BlockPool>
|
||||
{
|
||||
uint maxAllocCount_;
|
||||
size_t memBlockSize_;
|
||||
|
|
@ -180,7 +178,13 @@ namespace engine {
|
|||
bool
|
||||
isValid() const
|
||||
{
|
||||
return blockList_;
|
||||
return bool(blockList_);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -67,7 +67,6 @@
|
|||
#define PROC_MOBJECT_MODEL_PORT_H
|
||||
|
||||
#include "proc/asset/pipe.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "proc/streamtype.hpp"
|
||||
|
||||
namespace proc {
|
||||
|
|
@ -103,7 +102,6 @@ namespace mobject {
|
|||
* @see ModelPortRegistry_test abstract usage example
|
||||
*/
|
||||
class ModelPort
|
||||
: public lib::BoolCheckable<ModelPort>
|
||||
{
|
||||
ID<asset::Pipe> id_;
|
||||
|
||||
|
|
@ -129,6 +127,12 @@ namespace mobject {
|
|||
return exists (this->id_);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
|
||||
friend bool
|
||||
operator== (ModelPort const& mp1, ModelPort const& mp2)
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@
|
|||
#include "lib/util.hpp"
|
||||
#include "lib/hash-value.h"
|
||||
#include "proc/asset/pipe.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "common/query.hpp"
|
||||
|
||||
#include <boost/operators.hpp>
|
||||
|
|
@ -159,10 +158,8 @@ namespace mobject {
|
|||
* @note depends on the template parameter of the enclosing OutputMapping type!
|
||||
*/
|
||||
class Resolver
|
||||
: public lib::BoolCheckable<Resolver // bool conversion to signal "unconnected"...
|
||||
, boost::equality_comparable<Resolver, Target, // final mapping result can be compared to Target...
|
||||
boost::equality_comparable<Resolver> // mapping values can be compared.
|
||||
> > //
|
||||
: public boost::equality_comparable<Resolver, Target // final mapping result can be compared to Target...
|
||||
, boost::equality_comparable<Resolver>> // mapping values can be compared.
|
||||
{
|
||||
OutputMapping& thisMapping_;
|
||||
HashVal& pID_;
|
||||
|
|
@ -230,6 +227,12 @@ namespace mobject {
|
|||
return bool(pID_);
|
||||
}
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
|
||||
/* === equality comparisons (boost::operators) === */
|
||||
|
||||
|
|
|
|||
|
|
@ -66,7 +66,6 @@
|
|||
#define MOBJECT_PLACEMENT_REF_H
|
||||
|
||||
#include "lib/error.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "proc/mobject/placement.hpp"
|
||||
#include "proc/mobject/explicitplacement.hpp" /////////////TODO this is ugly! Why can't placement::resolve() return a reference??
|
||||
#include "proc/mobject/session/session-service-fetch.hpp"
|
||||
|
|
@ -98,7 +97,6 @@ namespace proc {
|
|||
*/
|
||||
template<class MX =MObject>
|
||||
class PlacementRef
|
||||
: public lib::BoolCheckable<PlacementRef<MX>>
|
||||
{
|
||||
typedef Placement<MX> PlacementMX;
|
||||
typedef Placement<MObject>::ID _ID;
|
||||
|
|
@ -206,6 +204,12 @@ namespace proc {
|
|||
|
||||
/* == forwarding part of the Placement-API == */
|
||||
|
||||
explicit
|
||||
operator bool() const
|
||||
{
|
||||
return isValid();
|
||||
}
|
||||
|
||||
bool isValid() const
|
||||
{
|
||||
if (checkValidity())
|
||||
|
|
|
|||
|
|
@ -88,7 +88,6 @@
|
|||
#define PROC_MOBJECT_SESSION_SCOPE_PATH_H
|
||||
|
||||
#include "proc/mobject/session/scope.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/iter-adapter.hpp"
|
||||
#include "lib/error.hpp"
|
||||
|
||||
|
|
@ -137,7 +136,6 @@ namespace session {
|
|||
* and QueryFocus to establish the \em current focus (path).
|
||||
*/
|
||||
class ScopePath
|
||||
: public lib::BoolCheckable<ScopePath>
|
||||
{
|
||||
size_t refcount_;
|
||||
std::vector<Scope> path_;
|
||||
|
|
@ -157,6 +155,8 @@ namespace session {
|
|||
|
||||
static const ScopePath INVALID;
|
||||
|
||||
explicit operator bool() const { return isValid(); }
|
||||
|
||||
|
||||
/* == state diagnostics == */
|
||||
bool isValid() const;
|
||||
|
|
|
|||
|
|
@ -2,27 +2,6 @@ TESTING "Metaprogramming facilities and techniques" ./test-suite --group=common
|
|||
|
||||
|
||||
|
||||
TEST "implicit conversion to bool" BoolCheckable_test <<END
|
||||
out: 1
|
||||
out: 2
|
||||
out: doIt
|
||||
out: 4
|
||||
out: 5
|
||||
out: doIt
|
||||
out: 7
|
||||
out: 8
|
||||
out: doIt
|
||||
out: 10
|
||||
out: 11
|
||||
out: doIt
|
||||
out: 13
|
||||
out: 14
|
||||
out: doIt
|
||||
out: sizeof. ExampleCustomType123 . = [248]
|
||||
return: 0
|
||||
END
|
||||
|
||||
|
||||
TEST "ConfigFlags_test" ConfigFlags_test <<END
|
||||
out-lit: Conf0 :-
|
||||
out-lit: Conf1 :-<1>-
|
||||
|
|
|
|||
|
|
@ -142,12 +142,12 @@ namespace test{
|
|||
, bind (&HavocThread::doIt, this)
|
||||
)
|
||||
{
|
||||
CHECK (thread_);
|
||||
CHECK (thread_.isValid());
|
||||
}
|
||||
|
||||
~HavocThread ()
|
||||
{
|
||||
if (thread_)
|
||||
if (thread_.isValid())
|
||||
thread_.join();
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -161,8 +161,8 @@ namespace test{
|
|||
Thread ping ("SyncWaiting ping", bind (&Token::getIt, &tok));
|
||||
Thread pong ("SyncWaiting pong", bind (&Token::getIt, &tok));
|
||||
|
||||
CHECK (ping);
|
||||
CHECK (pong);
|
||||
CHECK (ping.isValid());
|
||||
CHECK (pong.isValid());
|
||||
CHECK (0 == tok.result());
|
||||
|
||||
usleep (100000); // if the threads don't block correctly, they've missed their chance by now...
|
||||
|
|
|
|||
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
BoolCheckable(Test) - verify the mixin for implicit conversion to bool
|
||||
|
||||
Copyright (C) Lumiera.org
|
||||
2009, Hermann Vosseler <Ichthyostega@web.de>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
|
||||
* *****************************************************/
|
||||
|
||||
/** @file bool-checkable-test.cpp
|
||||
** unit test \ref BoolCheckable_test
|
||||
*/
|
||||
|
||||
|
||||
#include "lib/test/run.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
#include "lib/test/test-helper.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
using std::cout;
|
||||
using lib::test::showSizeof;
|
||||
|
||||
|
||||
namespace lib {
|
||||
namespace test{
|
||||
|
||||
/**
|
||||
* An example custom type,
|
||||
* which provides an implicit bool conversion
|
||||
* to express some special validity check.
|
||||
*/
|
||||
|
||||
class ExampleCustomType123
|
||||
: public lib::BoolCheckable<ExampleCustomType123>
|
||||
{
|
||||
|
||||
int val_;
|
||||
|
||||
public:
|
||||
|
||||
ExampleCustomType123 (int i)
|
||||
: val_(i)
|
||||
{ }
|
||||
|
||||
/** implements the custom logic to decide
|
||||
* if this instance can be considered "valid"
|
||||
*/
|
||||
bool
|
||||
isValid() const
|
||||
{
|
||||
return val_ % 3;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/******************************************************//**
|
||||
* @test verify the implementation of a validity check,
|
||||
* to be accessed as an implicit conversion to bool.
|
||||
*
|
||||
* @see lib::BoolCheckable
|
||||
* @todo list some usage examples here
|
||||
*/
|
||||
class BoolCheckable_test : public Test
|
||||
{
|
||||
|
||||
virtual void
|
||||
run (Arg)
|
||||
{
|
||||
for (int i=1; i<16; ++i)
|
||||
{
|
||||
ExampleCustomType123 test (i);
|
||||
|
||||
if (!test)
|
||||
cout << "doIt \n";
|
||||
if (test)
|
||||
cout << i << "\n";
|
||||
|
||||
CHECK (test.isValid() == bool(test) );
|
||||
CHECK (test.isValid() != !test);
|
||||
}
|
||||
|
||||
cout << showSizeof<ExampleCustomType123>() <<"\n";
|
||||
CHECK (sizeof (int) == sizeof (ExampleCustomType123));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** Register this test class... */
|
||||
LAUNCHER (BoolCheckable_test, "unit common");
|
||||
|
||||
|
||||
}} // namespace lib::test
|
||||
|
|
@ -30,9 +30,7 @@
|
|||
#include "lib/test/test-helper.hpp"
|
||||
#include "lib/util.hpp"
|
||||
#include "lib/util-foreach.hpp"
|
||||
|
||||
#include "lib/opaque-holder.hpp"
|
||||
#include "lib/bool-checkable.hpp"
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
|
|
@ -81,7 +79,6 @@ namespace test{
|
|||
|
||||
struct Special
|
||||
: DD<7>
|
||||
, BoolCheckable<Special>
|
||||
{
|
||||
ulong myVal_;
|
||||
|
||||
|
|
@ -89,8 +86,8 @@ namespace test{
|
|||
: myVal_(val)
|
||||
{ }
|
||||
|
||||
bool
|
||||
isValid () const ///< custom boolean "validity" check
|
||||
explicit
|
||||
operator bool() const ///< custom boolean "validity" check
|
||||
{
|
||||
return myVal_ % 2;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue