diff --git a/doc/technical/overview.txt b/doc/technical/overview.txt index 634e44c62..5ad3d6c23 100644 --- a/doc/technical/overview.txt +++ b/doc/technical/overview.txt @@ -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 diff --git a/src/backend/thread-wrapper.hpp b/src/backend/thread-wrapper.hpp index 07da15aed..37f1d834b 100644 --- a/src/backend/thread-wrapper.hpp +++ b/src/backend/thread-wrapper.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 // baseclass + : public Thread { public: ThreadJoinable (Literal purpose, Operation const& operation, diff --git a/src/common/query.hpp b/src/common/query.hpp index 9ab051b60..55347b3a3 100644 --- a/src/common/query.hpp +++ b/src/common/query.hpp @@ -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 { 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 }; diff --git a/src/lib/bool-checkable.hpp b/src/lib/bool-checkable.hpp deleted file mode 100644 index 529ee521b..000000000 --- a/src/lib/bool-checkable.hpp +++ /dev/null @@ -1,142 +0,0 @@ -/* - BOOL-CHECKABLE.hpp - mixin template for defining a safe conversion to bool - - Copyright (C) Lumiera.org - 2009, Hermann Vosseler - - 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 - -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 (*this); - - return (obj.*isValid)()? isValid : 0; - } - - bool operator! () const ///< never throws - { - ValidityCheck isValid (&T::isValid); - T const& obj = static_cast (*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 diff --git a/src/lib/iter-adapter-ptr-deref.hpp b/src/lib/iter-adapter-ptr-deref.hpp index 93968457b..ca4a5b958 100644 --- a/src/lib/iter-adapter-ptr-deref.hpp +++ b/src/lib/iter-adapter-ptr-deref.hpp @@ -85,7 +85,6 @@ namespace lib { */ template class PtrDerefIter - : public lib::BoolCheckable> { 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 AddressExposingIter - : public lib::BoolCheckable> { typedef typename IT::pointer _Ptr; @@ -265,6 +266,7 @@ namespace lib { takeAddress(); } + operator bool() const { return isValid(); } diff --git a/src/lib/iter-adapter-stl.hpp b/src/lib/iter-adapter-stl.hpp index 1a97f5527..13b91a17d 100644 --- a/src/lib/iter-adapter-stl.hpp +++ b/src/lib/iter-adapter-stl.hpp @@ -55,7 +55,6 @@ namespace iter_stl { */ template class DistinctIter - : public lib::BoolCheckable> { 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 class IterSnapshot - : public lib::BoolCheckable> { typedef std::vector Sequence; @@ -456,6 +456,8 @@ namespace iter_stl { buffer_.push_back(*p); } + operator bool() const { return isValid(); } + /* === lumiera forward iterator concept === */ diff --git a/src/lib/iter-adapter.hpp b/src/lib/iter-adapter.hpp index befcccf4d..5a9014425 100644 --- a/src/lib/iter-adapter.hpp +++ b/src/lib/iter-adapter.hpp @@ -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 IterAdapter - : public lib::BoolCheckable> { 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 class IterStateWrapper - : public lib::BoolCheckable> { 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 RangeIter - : public lib::BoolCheckable> { 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 class NumIter - : public lib::BoolCheckable> { 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 ConstIter - : public lib::BoolCheckable> { IT i_; ///< nested source iterator @@ -691,6 +693,7 @@ namespace lib { : i_(srcIter) { } + operator bool() const { return isValid(); } diff --git a/src/lib/itertools.hpp b/src/lib/itertools.hpp index b3fa64072..1b08009ae 100644 --- a/src/lib/itertools.hpp +++ b/src/lib/itertools.hpp @@ -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 IterTool - : public lib::BoolCheckable> { 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 === */ diff --git a/src/lib/meta/function-erasure.hpp b/src/lib/meta/function-erasure.hpp index 9c888754b..736ce4f80 100644 --- a/src/lib/meta/function-erasure.hpp +++ b/src/lib/meta/function-erasure.hpp @@ -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 { 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, diff --git a/src/lib/opaque-holder.hpp b/src/lib/opaque-holder.hpp index ddbe8ae48..58f23cb31 100644 --- a/src/lib/opaque-holder.hpp +++ b/src/lib/opaque-holder.hpp @@ -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> { typedef typename AccessPolicy::Base * BaseP; @@ -475,6 +473,12 @@ namespace lib { { return buff().isValid(); } + + explicit + operator bool() const + { + return isValid(); + } }; diff --git a/src/lib/optional-ref.hpp b/src/lib/optional-ref.hpp index ccdb72fe1..e4ff6ca15 100644 --- a/src/lib/optional-ref.hpp +++ b/src/lib/optional-ref.hpp @@ -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 class OptionalRef - : public lib::BoolCheckable> { T* ref_; @@ -82,6 +80,9 @@ namespace lib { : ref_(&target) { } + explicit operator bool() const { return isValid(); } + + T& operator() () const { diff --git a/src/lib/scoped-holder.hpp b/src/lib/scoped-holder.hpp index 1113a894c..336215eb3 100644 --- a/src/lib/scoped-holder.hpp +++ b/src/lib/scoped-holder.hpp @@ -146,10 +146,9 @@ namespace lib { char content_[sizeof(TY)]; char created_; - typedef ScopedHolder _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 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 diff --git a/src/lib/searchpath.hpp b/src/lib/searchpath.hpp index 88a3f0c5b..822ae1b1e 100644 --- a/src/lib/searchpath.hpp +++ b/src/lib/searchpath.hpp @@ -34,7 +34,6 @@ #define COMMON_SEARCHPATH_H #include "lib/error.hpp" -#include "lib/bool-checkable.hpp" #include #include @@ -75,8 +74,7 @@ namespace lib { * @note #next picks the current component and advances the iteration. */ class SearchPathSplitter - : public BoolCheckable + : boost::noncopyable { string pathSpec_; sregex_iterator pos_, @@ -91,6 +89,8 @@ namespace lib { , end_() { } + explicit operator bool() const { return isValid(); } + bool isValid() const { diff --git a/src/lib/singleton-ref.hpp b/src/lib/singleton-ref.hpp index 14ee74ec6..35fba715c 100644 --- a/src/lib/singleton-ref.hpp +++ b/src/lib/singleton-ref.hpp @@ -42,7 +42,6 @@ #include "lib/error.hpp" -#include "lib/bool-checkable.hpp" #include @@ -57,8 +56,7 @@ namespace lib { */ template class AccessAsReference - : public lib::BoolCheckable - , 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 diff --git a/src/lib/thread-local.hpp b/src/lib/thread-local.hpp index 613807278..530da6038 100644 --- a/src/lib/thread-local.hpp +++ b/src/lib/thread-local.hpp @@ -36,7 +36,6 @@ #include "lib/error.hpp" -#include "lib/bool-checkable.hpp" #include #include @@ -55,8 +54,7 @@ namespace lib { */ template class ThreadLocalPtr - : public BoolCheckable< ThreadLocalPtr - , 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(); } diff --git a/src/lib/wrapper.hpp b/src/lib/wrapper.hpp index 9b044413b..b5edbe7ad 100644 --- a/src/lib/wrapper.hpp +++ b/src/lib/wrapper.hpp @@ -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 class ItemWrapper - : public BoolCheckable> { using TY_unconst = typename meta::UnConst::Type ; @@ -227,6 +225,11 @@ namespace wrapper { return *this; } + operator bool() const + { + return isValid(); + } + /* == value access == */ TY& @@ -259,7 +262,6 @@ namespace wrapper { */ template class ItemWrapper - : public BoolCheckable > { 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) { diff --git a/src/proc/control/command-closure.hpp b/src/proc/control/command-closure.hpp index 8f231e35a..b5c520153 100644 --- a/src/proc/control/command-closure.hpp +++ b/src/proc/control/command-closure.hpp @@ -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 { 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? diff --git a/src/proc/control/command-def.hpp b/src/proc/control/command-def.hpp index 512b80f44..d878ac531 100644 --- a/src/proc/control/command-def.hpp +++ b/src/proc/control/command-def.hpp @@ -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 + : boost::noncopyable { Symbol id_; Command prototype_; @@ -311,6 +309,8 @@ namespace control { } + explicit operator bool() const { return isValid(); } + bool isValid() const; diff --git a/src/proc/control/command-impl.hpp b/src/proc/control/command-impl.hpp index acbd517f3..d4499fefc 100644 --- a/src/proc/control/command-impl.hpp +++ b/src/proc/control/command-impl.hpp @@ -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 @@ -78,9 +77,7 @@ namespace control { * @see Mutation */ class CommandImpl - : public lib::BoolCheckable + : 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 diff --git a/src/proc/control/command-mutation.hpp b/src/proc/control/command-mutation.hpp index ca9a9c6c2..6cc9f5336 100644 --- a/src/proc/control/command-mutation.hpp +++ b/src/proc/control/command-mutation.hpp @@ -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" diff --git a/src/proc/control/command-op-closure.hpp b/src/proc/control/command-op-closure.hpp index 6105d9438..af01aed07 100644 --- a/src/proc/control/command-op-closure.hpp +++ b/src/proc/control/command-op-closure.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" diff --git a/src/proc/control/command.hpp b/src/proc/control/command.hpp index 2106b0dab..966750f3d 100644 --- a/src/proc/control/command.hpp +++ b/src/proc/control/command.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" diff --git a/src/proc/control/handling-pattern.hpp b/src/proc/control/handling-pattern.hpp index e983e3297..53c866b12 100644 --- a/src/proc/control/handling-pattern.hpp +++ b/src/proc/control/handling-pattern.hpp @@ -46,7 +46,6 @@ #include "lib/error.hpp" #include "lib/symbol.hpp" -#include "lib/bool-checkable.hpp" #include @@ -70,13 +69,13 @@ namespace control { * @todo couldn't that be replaced by a lib::Result instance?? */ class ExecResult - : public lib::BoolCheckable { 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 { 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: diff --git a/src/proc/control/memento-tie.hpp b/src/proc/control/memento-tie.hpp index d5ac10350..bdbb8452a 100644 --- a/src/proc/control/memento-tie.hpp +++ b/src/proc/control/memento-tie.hpp @@ -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 class MementoTie - : public lib::BoolCheckable, - equality_comparable - > > + : public equality_comparable> { typedef typename CommandSignature::CaptureSig SIG_cap; typedef typename CommandSignature::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 { diff --git a/src/proc/engine/buffhandle.hpp b/src/proc/engine/buffhandle.hpp index 38ec85666..6a631d5ca 100644 --- a/src/proc/engine/buffhandle.hpp +++ b/src/proc/engine/buffhandle.hpp @@ -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 { typedef StreamType::ImplFacade::DataBuffer Buff; @@ -130,6 +128,7 @@ namespace engine { // using standard copy operations + explicit operator bool() const { return isValid(); } void emit(); diff --git a/src/proc/engine/channel-descriptor.hpp b/src/proc/engine/channel-descriptor.hpp index ce4fd5ac0..a252f8da9 100644 --- a/src/proc/engine/channel-descriptor.hpp +++ b/src/proc/engine/channel-descriptor.hpp @@ -39,7 +39,6 @@ #include "lib/error.hpp" #include "lib/hash-value.h" #include "proc/streamtype.hpp" -#include "lib/bool-checkable.hpp" namespace proc { diff --git a/src/proc/engine/tracking-heap-block-provider.cpp b/src/proc/engine/tracking-heap-block-provider.cpp index d3c8a885a..a0d4d34dc 100644 --- a/src/proc/engine/tracking-heap-block-provider.cpp +++ b/src/proc/engine/tracking-heap-block-provider.cpp @@ -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 { 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: diff --git a/src/proc/mobject/model-port.hpp b/src/proc/mobject/model-port.hpp index 995d9dd45..f7878967e 100644 --- a/src/proc/mobject/model-port.hpp +++ b/src/proc/mobject/model-port.hpp @@ -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 { ID 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) diff --git a/src/proc/mobject/output-mapping.hpp b/src/proc/mobject/output-mapping.hpp index 19305c348..5667c2002 100644 --- a/src/proc/mobject/output-mapping.hpp +++ b/src/proc/mobject/output-mapping.hpp @@ -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 @@ -159,10 +158,8 @@ namespace mobject { * @note depends on the template parameter of the enclosing OutputMapping type! */ class Resolver - : public lib::BoolCheckable // mapping values can be compared. - > > // + : public boost::equality_comparable> // 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) === */ diff --git a/src/proc/mobject/placement-ref.hpp b/src/proc/mobject/placement-ref.hpp index 235802bf9..a9e11caeb 100644 --- a/src/proc/mobject/placement-ref.hpp +++ b/src/proc/mobject/placement-ref.hpp @@ -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 PlacementRef - : public lib::BoolCheckable> { typedef Placement PlacementMX; typedef Placement::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()) diff --git a/src/proc/mobject/session/scope-path.hpp b/src/proc/mobject/session/scope-path.hpp index 0d1b25bdc..c3d6acae9 100644 --- a/src/proc/mobject/session/scope-path.hpp +++ b/src/proc/mobject/session/scope-path.hpp @@ -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 { size_t refcount_; std::vector path_; @@ -157,6 +155,8 @@ namespace session { static const ScopePath INVALID; + explicit operator bool() const { return isValid(); } + /* == state diagnostics == */ bool isValid() const; diff --git a/tests/12metaprogramming.tests b/tests/12metaprogramming.tests index 0b5892fae..3998028cd 100644 --- a/tests/12metaprogramming.tests +++ b/tests/12metaprogramming.tests @@ -2,27 +2,6 @@ TESTING "Metaprogramming facilities and techniques" ./test-suite --group=common -TEST "implicit conversion to bool" BoolCheckable_test <- diff --git a/tests/backend/sync-locking-test.cpp b/tests/backend/sync-locking-test.cpp index 2bf1aea69..b73bdb147 100644 --- a/tests/backend/sync-locking-test.cpp +++ b/tests/backend/sync-locking-test.cpp @@ -142,12 +142,12 @@ namespace test{ , bind (&HavocThread::doIt, this) ) { - CHECK (thread_); + CHECK (thread_.isValid()); } ~HavocThread () { - if (thread_) + if (thread_.isValid()) thread_.join(); } }; diff --git a/tests/backend/sync-waiting-test.cpp b/tests/backend/sync-waiting-test.cpp index 8533c3c28..06191de09 100644 --- a/tests/backend/sync-waiting-test.cpp +++ b/tests/backend/sync-waiting-test.cpp @@ -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... diff --git a/tests/library/bool-checkable-test.cpp b/tests/library/bool-checkable-test.cpp deleted file mode 100644 index ae1a3c1c8..000000000 --- a/tests/library/bool-checkable-test.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - BoolCheckable(Test) - verify the mixin for implicit conversion to bool - - Copyright (C) Lumiera.org - 2009, Hermann Vosseler - - 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 - -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 - { - - 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() <<"\n"; - CHECK (sizeof (int) == sizeof (ExampleCustomType123)); - } - }; - - - /** Register this test class... */ - LAUNCHER (BoolCheckable_test, "unit common"); - - -}} // namespace lib::test diff --git a/tests/library/opaque-holder-test.cpp b/tests/library/opaque-holder-test.cpp index cc8a8a371..2b048d294 100644 --- a/tests/library/opaque-holder-test.cpp +++ b/tests/library/opaque-holder-test.cpp @@ -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 #include @@ -81,7 +79,6 @@ namespace test{ struct Special : DD<7> - , BoolCheckable { 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; }