From 9e0c7147988776688817d16d5db0b9c923838b4b Mon Sep 17 00:00:00 2001 From: ADAM David Alan Martin Date: Thu, 30 May 2024 19:50:58 -0400 Subject: [PATCH] Avoid type confusion in exceptions. When creating these typedefs, if we use in-place declared types, we wind up with surprising aliasing of various types, via namespace exposure. --- Atomic/Dropbox.h | 14 +++++++---- Atomic/Mailbox.h | 14 +++++++---- Atomic/Mailbox.test/0.cc | 12 +++++++--- Exception.h | 50 ++++++++++++++++++++++------------------ Thread.h | 3 ++- Thread.test/thread.cc | 3 ++- 6 files changed, 61 insertions(+), 35 deletions(-) diff --git a/Atomic/Dropbox.h b/Atomic/Dropbox.h index 68c4ff1..6fbde60 100644 --- a/Atomic/Dropbox.h +++ b/Atomic/Dropbox.h @@ -31,15 +31,18 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Dropbox_m const bool debugPop= false or C::debug; } + + enum Dropbox_tag {}; + inline namespace exports { template< typename > class Dropbox; - using DropboxFinishedException= synthetic_exception< struct finished_exception, FinishedException >; + using DropboxFinishedException= synthetic_exception< Dropbox_tag, FinishedException >; using AnyTaggedDropboxFinishedException= AnyTagged< DropboxFinishedException >; template< typename tag > using TaggedDropboxFinishedException= Tagged< DropboxFinishedException, tag >; - using DropboxFinishedCondition= synthetic_exception< struct finished_exception, FinishedCondition, DropboxFinishedException >; + using DropboxFinishedCondition= synthetic_exception< Dropbox_tag, FinishedCondition, DropboxFinishedException >; using AnyTaggedDropboxFinishedCondition= AnyTagged< DropboxFinishedCondition >; template< typename tag > using TaggedDropboxFinishedCondition= Tagged< DropboxFinishedCondition, tag >; } @@ -71,12 +74,15 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Dropbox_m template< typename Item > class exports::Dropbox { + private: + enum Finished_tag {}; + public: - using FinishedException= synthetic_exception< struct finished_exception, DropboxFinishedException >; + using FinishedException= synthetic_exception< Dropbox_tag, DropboxFinishedException >; //using AnyTaggedFinishedException= AnyTagged< FinishedException >; //template< typename tag > using TaggedFinishedException= Tagged< FinishedException, tag >; - using FinishedCondition= synthetic_exception< struct finished_exception, DropboxFinishedCondition, FinishedException >; + using FinishedCondition= synthetic_exception< Dropbox_tag, DropboxFinishedCondition, FinishedException >; //using AnyTaggedFinishedCondition= AnyTagged< FinishedCondition >; //template< typename tag > using TaggedFinishedCondition= Tagged< FinishedCondition, tag >; diff --git a/Atomic/Mailbox.h b/Atomic/Mailbox.h index d420327..3f74ac3 100644 --- a/Atomic/Mailbox.h +++ b/Atomic/Mailbox.h @@ -29,15 +29,18 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m const bool debugPop= false or C::debug; } + + enum Mailbox_tag {}; + inline namespace exports { template< typename > class Mailbox; - using MailboxFinishedException= synthetic_exception< struct finished_exception, FinishedException >; + using MailboxFinishedException= synthetic_exception< Mailbox_tag, FinishedException >; using AnyTaggedMailboxFinishedException= AnyTagged< MailboxFinishedException >; template< typename tag > using TaggedMailboxFinishedException= Tagged< MailboxFinishedException, tag >; - using MailboxFinishedCondition= synthetic_exception< struct finished_exception, FinishedCondition, MailboxFinishedException >; + using MailboxFinishedCondition= synthetic_exception< Mailbox_tag, FinishedCondition, MailboxFinishedException >; using AnyTaggedMailboxFinishedCondition= AnyTagged< MailboxFinishedCondition >; template< typename tag > using TaggedMailboxFinishedCondition= Tagged< MailboxFinishedCondition, tag >; } @@ -74,12 +77,15 @@ namespace Alepha::Hydrogen::Atomic ::detail:: Mailbox_m template< typename Item > class exports::Mailbox { + private: + enum Finished_tag {}; + public: - using FinishedException= synthetic_exception< struct finished_exception, MailboxFinishedException >; + using FinishedException= synthetic_exception< Finished_tag, MailboxFinishedException >; //using AnyTaggedFinishedException= AnyTagged< FinishedException >; //template< typename tag > using TaggedFinishedException= Tagged< FinishedException, tag >; - using FinishedCondition= synthetic_exception< struct finished_exception, MailboxFinishedCondition, FinishedException >; + using FinishedCondition= synthetic_exception< Finished_tag, MailboxFinishedCondition, FinishedException >; //using AnyTaggedFinishedCondition= AnyTagged< FinishedCondition >; //template< typename tag > using TaggedFinishedCondition= Tagged< FinishedCondition, tag >; diff --git a/Atomic/Mailbox.test/0.cc b/Atomic/Mailbox.test/0.cc index c420352..85d6859 100644 --- a/Atomic/Mailbox.test/0.cc +++ b/Atomic/Mailbox.test/0.cc @@ -1,6 +1,7 @@ static_assert( __cplusplus > 2020'99 ); #include "../Mailbox.h" +#include "../Dropbox.h" #include #include @@ -14,7 +15,7 @@ static auto init= Alepha::Utility::enroll <=[] "Smoke Test"_test <=[] { - Alepha::Atomic::Mailbox< int > m( 1024 ); + Alepha::Atomic::Dropbox< int > m( 1024 ); m.push( 42 ); m.push( 42 ); @@ -34,17 +35,22 @@ static auto init= Alepha::Utility::enroll <=[] std::cerr << "We caught an exception." << std::endl; const Alepha::Exception *const cond_p= &cond; - assert( dynamic_cast< const Alepha::Atomic::MailboxFinishedException * >( cond_p ) ); + assert( not dynamic_cast< const Alepha::Atomic::MailboxFinishedException * >( cond_p ) ); + assert( dynamic_cast< const Alepha::Atomic::DropboxFinishedException * >( cond_p ) ); + assert( dynamic_cast< const Alepha::FinishedException * >( cond_p ) ); assert( dynamic_cast< const Alepha::Exception * >( cond_p ) ); - assert( dynamic_cast< const Alepha::Atomic::MailboxFinishedCondition * >( cond_p ) ); + assert( not dynamic_cast< const Alepha::Atomic::MailboxFinishedCondition * >( cond_p ) ); + assert( dynamic_cast< const Alepha::Atomic::DropboxFinishedCondition * >( cond_p ) ); + assert( dynamic_cast< const Alepha::FinishedCondition * >( cond_p ) ); assert( dynamic_cast< const Alepha::Condition * >( cond_p ) ); assert( not dynamic_cast< const Alepha::Atomic::AnyTaggedMailboxFinishedException * >( cond_p ) ); + assert( not dynamic_cast< const Alepha::Atomic::AnyTaggedDropboxFinishedException * >( cond_p ) ); assert( not dynamic_cast< const Alepha::AnyTaggedFinishedException * >( cond_p ) ); assert( not dynamic_cast< const Alepha::AnyTaggedException * >( cond_p ) ); diff --git a/Exception.h b/Exception.h index 8ad7d5c..0849c0b 100644 --- a/Exception.h +++ b/Exception.h @@ -74,12 +74,12 @@ namespace Alepha::Hydrogen ::detail:: Exception_m template< typename ... Bases > struct bases : virtual public Bases... {}; - template< typename unique, typename GradeType, typename Bases > + template< Enumeration unique, typename GradeType, typename Bases > class synthetic_any_tagged_type { }; - template< typename unique_handle, typename GradeType, typename ... Bases > + template< Enumeration unique_handle, typename GradeType, typename ... Bases > class synthetic_exception : virtual public bases< GradeType, Bases... > { @@ -122,7 +122,7 @@ namespace Alepha::Hydrogen ::detail:: Exception_m template< typename T > concept ExceptionGrade= list_contains_v< Grades, T >; - template< typename unique_handle, ExceptionGrade GradeType, typename ... Bases > + template< Enumeration unique_handle, ExceptionGrade GradeType, typename ... Bases > using create_exception= synthetic_exception< unique_handle, GradeType, Bases ... >; template< typename Exc > @@ -314,6 +314,7 @@ namespace Alepha::Hydrogen ::detail:: Exception_m template< typename T > concept DerivedFromError= std::is_base_of_v< Error, T >; + enum NamedResource_tag {}; class NamedResourceStorage; class NamedResourceInterface { @@ -332,52 +333,55 @@ namespace Alepha::Hydrogen ::detail:: Exception_m public: std::string_view resourceName() const noexcept final { return storage; } }; - class NamedResourceException : public virtual create_exception< struct named_resource_throwable, Exception >, virtual public NamedResourceInterface {}; + class NamedResourceException : public virtual create_exception< NamedResource_tag, Exception >, virtual public NamedResourceInterface {}; using AnyTaggedNamedResourceException= NamedResourceException::any_tagged_type; template< typename tag > using TaggedNamedResourceException= NamedResourceException::tagged_type< tag >; - using NamedResourceNotification= create_exception< struct named_resource_notification, Notification, NamedResourceException >; + using NamedResourceNotification= create_exception< NamedResource_tag, Notification, NamedResourceException >; using AnyTaggedNamedResourceNotification= NamedResourceNotification::any_tagged_type; template< typename tag > using TaggedNamedResourceNotification= NamedResourceNotification::tagged_type< tag >; - using NamedResourceError= create_exception< struct named_resource_exception, Error, NamedResourceException >; + using NamedResourceError= create_exception< NamedResource_tag, Error, NamedResourceException >; using AnyTaggedNamedResourceError= NamedResourceError::any_tagged_type; template< typename tag > using TaggedNamedResourceError= NamedResourceError::tagged_type< tag >; - using NamedResourceCriticalError= create_exception< struct named_resource_error, CriticalError, NamedResourceException >; + using NamedResourceCriticalError= create_exception< NamedResource_tag, CriticalError, NamedResourceException >; using AnyTaggedNamedResourceCriticalError= NamedResourceCriticalError::any_tagged_type; template< typename tag > using TaggedNamedResourceCriticalError= NamedResourceCriticalError::tagged_type< tag >; - using NamedResourceViolation= create_exception< struct named_resource_violation, Violation, NamedResourceException >; + using NamedResourceViolation= create_exception< NamedResource_tag, Violation, NamedResourceException >; using AnyTaggedNamedResourceViolation= NamedResourceViolation::any_tagged_type; template< typename tag > using TaggedNamedResourceViolation= NamedResourceViolation::tagged_type< tag >; + enum OutOfRange_tag {}; + class OutOfRangeException - : virtual public create_exception< struct out_of_range_throwable, Exception > {}; + : virtual public create_exception< OutOfRange_tag, Exception > {}; using AnyTaggedOutOfRangeException= OutOfRangeException::any_tagged_type; template< typename tag > using TaggedOutOfRangeException= OutOfRangeException::tagged_type< tag >; - using OutOfRangeError= create_exception< struct out_of_range_throwable, Error, OutOfRangeException >; + using OutOfRangeError= create_exception< OutOfRange_tag, Error, OutOfRangeException >; using AnyTaggedOutOfRangeError= OutOfRangeError::any_tagged_type; template< typename tag > using TaggedOutOfRangeError= OutOfRangeError::tagged_type< tag >; - using OutOfRangeCriticalError= create_exception< struct out_of_range_throwable, CriticalError, OutOfRangeException >; + using OutOfRangeCriticalError= create_exception< OutOfRange_tag, CriticalError, OutOfRangeException >; using AnyTaggedOutOfRangeCriticalError= OutOfRangeCriticalError::any_tagged_type; template< typename tag > using TaggedOutOfRangeCriticalError= OutOfRangeCriticalError::tagged_type< tag >; - using OutOfRangeViolation= create_exception< struct out_of_range_throwable, Violation, OutOfRangeException >; + using OutOfRangeViolation= create_exception< OutOfRange_tag, Violation, OutOfRangeException >; using AnyTaggedOutOfRangeViolation= OutOfRangeViolation::any_tagged_type; template< typename tag > using TaggedOutOfRangeViolation= OutOfRangeViolation::tagged_type< tag >; + enum IndexOutOfRange_tag {}; class IndexedRangeInformationStorage; class IndexedRangeInformationInterface { @@ -402,26 +406,26 @@ namespace Alepha::Hydrogen ::detail:: Exception_m std::size_t requested() const noexcept override { return request; } }; class IndexOutOfRangeException - : virtual public create_exception< struct index_out_of_range_throwable, Exception, OutOfRangeException > {}; + : virtual public create_exception< IndexOutOfRange_tag, Exception, OutOfRangeException > {}; using AnyTaggedIndexOutOfRangeException= IndexOutOfRangeException::any_tagged_type; template< typename tag > using TaggedIndexOutOfRangeException= IndexOutOfRangeException::tagged_type< tag >; class IndexOutOfRangeError - : virtual public create_exception< struct index_out_of_range_throwable, Error, OutOfRangeError, IndexOutOfRangeException > {}; + : virtual public create_exception< IndexOutOfRange_tag, Error, OutOfRangeError, IndexOutOfRangeException > {}; using AnyTaggedIndexOutOfRangeException= IndexOutOfRangeException::any_tagged_type; template< typename tag > using TaggedIndexOutOfRangeException= IndexOutOfRangeException::tagged_type< tag >; class IndexOutOfRangeCriticalError - : virtual public create_exception< struct index_out_of_range_throwable, CriticalError, OutOfRangeCriticalError, IndexOutOfRangeException > {}; + : virtual public create_exception< IndexOutOfRange_tag, CriticalError, OutOfRangeCriticalError, IndexOutOfRangeException > {}; using AnyTaggedIndexOutOfRangeCriticalError= IndexOutOfRangeCriticalError::any_tagged_type; template< typename tag > using TaggedIndexOutOfRangeCriticalError= IndexOutOfRangeCriticalError::tagged_type< tag >; class IndexOutOfRangeViolation - : virtual public create_exception< struct index_out_of_range_throwable, Violation, OutOfRangeViolation, IndexOutOfRangeException > {}; + : virtual public create_exception< IndexOutOfRange_tag, Violation, OutOfRangeViolation, IndexOutOfRangeException > {}; using AnyTaggedIndexOutOfRangeViolation= IndexOutOfRangeViolation::any_tagged_type; template< typename tag > using TaggedIndexOutOfRangeViolation= IndexOutOfRangeViolation::tagged_type< tag >; @@ -444,23 +448,24 @@ namespace Alepha::Hydrogen ::detail:: Exception_m public: std::size_t allocationAmount() const noexcept final { return amount; } }; + enum Allocation_tag {}; class AllocationException - : virtual public create_exception< struct allocation_throwable, Exception >, virtual public AllocationAmountInterface {}; + : virtual public create_exception< Allocation_tag, Exception >, virtual public AllocationAmountInterface {}; using AnyTaggedAllocationException= AllocationException::any_tagged_type; template< typename tag > using TaggedAllocationException= AllocationException::tagged_type< tag >; - using AllocationError= create_exception< struct allocation_exception, Error, AllocationException >; + using AllocationError= create_exception< Allocation_tag, Error, AllocationException >; using AnyTaggedAllocationError= AllocationError::any_tagged_type; template< typename tag > using TaggedAllocationError= AllocationError::tagged_type< tag >; - using AllocationCriticalError= create_exception< struct allocation_error, CriticalError, AllocationException >; + using AllocationCriticalError= create_exception< Allocation_tag, CriticalError, AllocationException >; using AnyTaggedAllocationCriticalError= AllocationCriticalError::any_tagged_type; template< typename tag > using TaggedAllocationCriticalError= AllocationCriticalError::tagged_type< tag >; - using AllocationViolation= create_exception< struct allocation_violation, Violation, AllocationException >; + using AllocationViolation= create_exception< Allocation_tag, Violation, AllocationException >; using AnyTaggedAllocationViolation= AllocationViolation::any_tagged_type; template< typename tag > using TaggedAllocationViolation= AllocationViolation::tagged_type< tag >; @@ -564,11 +569,12 @@ namespace Alepha::Hydrogen ::detail:: Exception_m } } - using FinishedException= create_exception< struct finished_exception, Exception >; + enum Finished_tag {}; + using FinishedException= create_exception< Finished_tag, Exception >; using AnyTaggedFinishedException= AnyTagged< FinishedException >; template< typename tag > using TaggedFinishedException= Tagged< FinishedException, tag >; - using FinishedCondition= create_exception< struct finished_condition, Condition, FinishedException >; + using FinishedCondition= create_exception< Finished_tag, Condition, FinishedException >; using AnyTaggedFinishedCondition= AnyTagged< FinishedCondition >; template< typename tag > using TaggedFinishedCondition= Tagged< FinishedCondition, tag >; } diff --git a/Thread.h b/Thread.h index 072a42d..5f05123 100644 --- a/Thread.h +++ b/Thread.h @@ -15,7 +15,8 @@ namespace Alepha::Hydrogen ::detail:: Thread_m { inline namespace exports { - using CrossThreadNotificationRethrowError= synthetic_exception< struct cross_thread_notification_failure, Error >; + enum CrossThread_tag {}; + using CrossThreadNotificationRethrowError= synthetic_exception< CrossThread_tag, Error >; namespace this_thread { //void sleep( std::chrono::duration ); diff --git a/Thread.test/thread.cc b/Thread.test/thread.cc index 5f41a6a..a9859da 100644 --- a/Thread.test/thread.cc +++ b/Thread.test/thread.cc @@ -16,7 +16,8 @@ namespace namespace util= Alepha::Utility; using namespace Alepha::Testing::exports; - using MyNotification= Alepha::create_exception< struct my_notification, Alepha::Notification >; + enum my_notification_tag {}; + using MyNotification= Alepha::create_exception< my_notification_tag, Alepha::Notification >; auto tests= Alepha::Utility::enroll <=[] {