You can subscribe to this list here.
2005 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
(80) |
Aug
(36) |
Sep
(120) |
Oct
(89) |
Nov
(57) |
Dec
(22) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2006 |
Jan
(308) |
Feb
(66) |
Mar
(88) |
Apr
(54) |
May
(43) |
Jun
(40) |
Jul
(33) |
Aug
(1) |
Sep
(7) |
Oct
(65) |
Nov
(19) |
Dec
(10) |
2007 |
Jan
(5) |
Feb
(8) |
Mar
(7) |
Apr
|
May
(7) |
Jun
|
Jul
(5) |
Aug
(3) |
Sep
(1) |
Oct
|
Nov
|
Dec
|
2008 |
Jan
|
Feb
|
Mar
(5) |
Apr
|
May
(5) |
Jun
(21) |
Jul
(27) |
Aug
(6) |
Sep
|
Oct
(1) |
Nov
(5) |
Dec
(10) |
2009 |
Jan
(67) |
Feb
(3) |
Mar
(26) |
Apr
(2) |
May
|
Jun
(1) |
Jul
|
Aug
(2) |
Sep
(10) |
Oct
(18) |
Nov
(20) |
Dec
(3) |
2010 |
Jan
|
Feb
|
Mar
(1) |
Apr
(1) |
May
|
Jun
|
Jul
|
Aug
|
Sep
(9) |
Oct
(3) |
Nov
|
Dec
|
2011 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(7) |
Jul
|
Aug
|
Sep
(39) |
Oct
(43) |
Nov
(7) |
Dec
|
2012 |
Jan
|
Feb
|
Mar
|
Apr
(6) |
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
2013 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(7) |
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
From: <syn...@us...> - 2009-12-22 11:35:53
|
Revision: 1066 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1066&view=rev Author: syntheticpp Date: 2009-12-22 11:35:46 +0000 (Tue, 22 Dec 2009) Log Message: ----------- make inheriting from Factory possible, thanks to Roland Pabel Modified Paths: -------------- trunk/include/loki/Factory.h Modified: trunk/include/loki/Factory.h =================================================================== --- trunk/include/loki/Factory.h 2009-12-14 17:01:10 UTC (rev 1065) +++ trunk/include/loki/Factory.h 2009-12-22 11:35:46 UTC (rev 1066) @@ -751,6 +751,7 @@ > class Factory : public FactoryErrorPolicy<IdentifierType, AbstractProduct> { + protected: typedef FactoryImpl< AbstractProduct, IdentifierType, CreatorParmTList > Impl; typedef typename Impl::Parm1 Parm1; @@ -771,6 +772,7 @@ typedef Functor<AbstractProduct*, CreatorParmTList> ProductCreator; + private: typedef AssocVector<IdentifierType, ProductCreator> IdToProductMap; IdToProductMap associations_; @@ -806,6 +808,11 @@ return associations_.erase(id) != 0; } + bool IsRegistered(const IdentifierType& id) + { + return associations_.find(id) != associations_.end(); + } + std::vector<IdentifierType> RegisteredIds() { std::vector<IdentifierType> ids; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-12-14 17:01:22
|
Revision: 1065 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1065&view=rev Author: syntheticpp Date: 2009-12-14 17:01:10 +0000 (Mon, 14 Dec 2009) Log Message: ----------- remove UTF-8 BOM Modified Paths: -------------- trunk/include/loki/ForEachType.h trunk/include/loki/StrongPtr.h Modified: trunk/include/loki/ForEachType.h =================================================================== --- trunk/include/loki/ForEachType.h 2009-11-22 10:55:24 UTC (rev 1064) +++ trunk/include/loki/ForEachType.h 2009-12-14 17:01:10 UTC (rev 1065) @@ -1,4 +1,3 @@ - //////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (C) 2009 Andy Balaam Modified: trunk/include/loki/StrongPtr.h =================================================================== --- trunk/include/loki/StrongPtr.h 2009-11-22 10:55:24 UTC (rev 1064) +++ trunk/include/loki/StrongPtr.h 2009-12-14 17:01:10 UTC (rev 1065) @@ -1,4 +1,4 @@ -//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2006 Rich Sposato // The copyright on this file is protected under the terms of the MIT license. This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-11-22 10:55:31
|
Revision: 1064 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1064&view=rev Author: syntheticpp Date: 2009-11-22 10:55:24 +0000 (Sun, 22 Nov 2009) Log Message: ----------- indent 4 spaces Modified Paths: -------------- trunk/include/loki/ForEachType.h Modified: trunk/include/loki/ForEachType.h =================================================================== --- trunk/include/loki/ForEachType.h 2009-11-21 10:54:19 UTC (rev 1063) +++ trunk/include/loki/ForEachType.h 2009-11-22 10:55:24 UTC (rev 1064) @@ -41,16 +41,16 @@ struct ForEachTypeImpl<Typelist<Head, Tail>, Callable> : public ForEachTypeImpl<Tail, Callable> { - enum { value = 1 + ForEachTypeImpl<Tail, Callable>::value }; + enum { value = 1 + ForEachTypeImpl<Tail, Callable>::value }; - ForEachTypeImpl( Callable& callable ) : ForEachTypeImpl<Tail, Callable>(callable) - { + ForEachTypeImpl( Callable& callable ) : ForEachTypeImpl<Tail, Callable>(callable) + { #ifdef _MSC_VER - callable.operator()<value, Head>(); + callable.operator()<value, Head>(); #else - callable.template operator()<value, Head>(); + callable.template operator()<value, Head>(); #endif - } + } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-11-21 10:54:28
|
Revision: 1063 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1063&view=rev Author: syntheticpp Date: 2009-11-21 10:54:19 +0000 (Sat, 21 Nov 2009) Log Message: ----------- msvc doesn't understand this C++ Modified Paths: -------------- trunk/include/loki/ForEachType.h Modified: trunk/include/loki/ForEachType.h =================================================================== --- trunk/include/loki/ForEachType.h 2009-11-21 10:47:12 UTC (rev 1062) +++ trunk/include/loki/ForEachType.h 2009-11-21 10:54:19 UTC (rev 1063) @@ -45,7 +45,11 @@ ForEachTypeImpl( Callable& callable ) : ForEachTypeImpl<Tail, Callable>(callable) { +#ifdef _MSC_VER callable.operator()<value, Head>(); +#else + callable.template operator()<value, Head>(); +#endif } }; @@ -60,7 +64,11 @@ ForEachTypeImpl( Callable& callable ) { +#ifdef _MSC_VER callable.operator()<value, Head>(); +#else + callable.template operator()<value, Head>(); +#endif } }; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-11-21 10:47:20
|
Revision: 1062 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1062&view=rev Author: syntheticpp Date: 2009-11-21 10:47:12 +0000 (Sat, 21 Nov 2009) Log Message: ----------- utf8 Modified Paths: -------------- trunk/include/loki/ForEachType.h Modified: trunk/include/loki/ForEachType.h =================================================================== --- trunk/include/loki/ForEachType.h 2009-11-21 10:44:43 UTC (rev 1061) +++ trunk/include/loki/ForEachType.h 2009-11-21 10:47:12 UTC (rev 1062) @@ -1,8 +1,8 @@ - + //////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (C) 2009 Andy Balaam -// Copyright (c) 2009 Peter K\xFCmmel +// Copyright (c) 2009 Peter Kümmel // Permission to use, copy, modify, distribute and sell this software for any // purpose is hereby granted without fee, provided that the above copyright // notice appear in all copies and that both that copyright notice and this This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-11-21 10:44:53
|
Revision: 1061 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1061&view=rev Author: syntheticpp Date: 2009-11-21 10:44:43 +0000 (Sat, 21 Nov 2009) Log Message: ----------- update studio files Modified Paths: -------------- trunk/test/Register/Register.sln trunk/test/Register/foo.vcproj trunk/test/Register/main.vcproj Modified: trunk/test/Register/Register.sln =================================================================== --- trunk/test/Register/Register.sln 2009-11-21 10:44:08 UTC (rev 1060) +++ trunk/test/Register/Register.sln 2009-11-21 10:44:43 UTC (rev 1061) @@ -1,6 +1,6 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual C++ Express 2005 +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual C++ Express 2008 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "foo", "foo.vcproj", "{42E13925-28CE-421B-993E-162510C90CD6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "main", "main.vcproj", "{237F4D1A-6301-4656-8F34-B0F6496E929F}" Modified: trunk/test/Register/foo.vcproj =================================================================== --- trunk/test/Register/foo.vcproj 2009-11-21 10:44:08 UTC (rev 1060) +++ trunk/test/Register/foo.vcproj 2009-11-21 10:44:43 UTC (rev 1061) @@ -1,10 +1,11 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="9,00" Name="foo" ProjectGUID="{42E13925-28CE-421B-993E-162510C90CD6}" RootNamespace="Foo" + TargetFrameworkVersion="131072" > <Platforms> <Platform @@ -183,10 +184,6 @@ RelativePath=".\foo.h" > </File> - <File - RelativePath="..\..\include\loki\Register.h" - > - </File> </Files> <Globals> </Globals> Modified: trunk/test/Register/main.vcproj =================================================================== --- trunk/test/Register/main.vcproj 2009-11-21 10:44:08 UTC (rev 1060) +++ trunk/test/Register/main.vcproj 2009-11-21 10:44:43 UTC (rev 1061) @@ -1,11 +1,12 @@ <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" - Version="8,00" + Version="9,00" Name="main" ProjectGUID="{237F4D1A-6301-4656-8F34-B0F6496E929F}" RootNamespace="main" Keyword="Win32Proj" + TargetFrameworkVersion="131072" > <Platforms> <Platform @@ -66,6 +67,8 @@ OutputFile="$(OutDir)\$(ProjectName).exe" AdditionalLibraryDirectories="..\..\loki\lib" GenerateDebugInformation="true" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" /> <Tool Name="VCALinkTool" @@ -86,9 +89,6 @@ Name="VCAppVerifierTool" /> <Tool - Name="VCWebDeploymentTool" - /> - <Tool Name="VCPostBuildEventTool" /> </Configuration> @@ -141,6 +141,8 @@ SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" + RandomizedBaseAddress="1" + DataExecutionPrevention="0" TargetMachine="1" /> <Tool @@ -162,9 +164,6 @@ Name="VCAppVerifierTool" /> <Tool - Name="VCWebDeploymentTool" - /> - <Tool Name="VCPostBuildEventTool" /> </Configuration> @@ -173,10 +172,22 @@ </References> <Files> <File + RelativePath="..\..\include\loki\ForEachType.h" + > + </File> + <File + RelativePath="..\..\include\loki\HierarchyGenerators.h" + > + </File> + <File RelativePath=".\main.cpp" > </File> <File + RelativePath="..\..\include\loki\Register.h" + > + </File> + <File RelativePath="..\..\src\Singleton.cpp" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-11-21 10:44:18
|
Revision: 1060 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1060&view=rev Author: syntheticpp Date: 2009-11-21 10:44:08 +0000 (Sat, 21 Nov 2009) Log Message: ----------- use foreach in register code, add foreach tests Modified Paths: -------------- trunk/include/loki/Register.h trunk/include/loki/StrongPtr.h trunk/test/Register/classlist.h trunk/test/Register/foo.cpp trunk/test/Register/main.cpp Modified: trunk/include/loki/Register.h =================================================================== --- trunk/include/loki/Register.h 2009-11-21 10:40:59 UTC (rev 1059) +++ trunk/include/loki/Register.h 2009-11-21 10:44:08 UTC (rev 1060) @@ -17,7 +17,9 @@ #include "TypeManip.h" #include "HierarchyGenerators.h" +#include "ForEachType.h" + /// \defgroup RegisterGroup Register namespace Loki @@ -33,41 +35,39 @@ /// \ingroup RegisterGroup /// Must be specialized be the user //////////////////////////////////////////////////////////////////////////////// - template<class t> bool RegisterFunction(); + template<class T> + bool RegisterFunction(); //////////////////////////////////////////////////////////////////////////////// /// \ingroup RegisterGroup /// Must be specialized be the user //////////////////////////////////////////////////////////////////////////////// - template<class t> bool UnRegisterFunction(); + template<class T> + bool UnRegisterFunction(); namespace Private { - template<class T> struct RegisterOnCreate { - RegisterOnCreate() { RegisterFunction<T>(); } + template< int Index, typename T > + void operator()() + { + RegisterFunction<T>(); + } }; - template<class T> struct UnRegisterOnDelete { - ~UnRegisterOnDelete() { UnRegisterFunction<T>(); } - }; - - template<class T> - struct RegisterOnCreateElement - { - RegisterOnCreate<T> registerObj; + template< int Index, typename T > + void operator()() + { + UnRegisterFunction<T>(); + } }; - template<class T> - struct UnRegisterOnDeleteElement - { - UnRegisterOnDelete<T> unregisterObj; - }; } + //////////////////////////////////////////////////////////////////////////////// /// \class RegisterOnCreateSet /// @@ -79,9 +79,14 @@ //////////////////////////////////////////////////////////////////////////////// template<typename ElementList> - struct RegisterOnCreateSet - : GenScatterHierarchy<ElementList, Private::RegisterOnCreateElement> - {}; + struct RegisterOnCreateSet + { + RegisterOnCreateSet() + { + Private::RegisterOnCreate d; + ForEachType< ElementList, Private::RegisterOnCreate > dummy(d); + } + }; //////////////////////////////////////////////////////////////////////////////// /// \class UnRegisterOnDeleteSet @@ -93,9 +98,14 @@ /// see test/Register //////////////////////////////////////////////////////////////////////////////// template<typename ElementList> - struct UnRegisterOnDeleteSet - : GenScatterHierarchy<ElementList, Private::UnRegisterOnDeleteElement> - {}; + struct UnRegisterOnDeleteSet + { + ~UnRegisterOnDeleteSet() + { + Private::UnRegisterOnDelete d; + ForEachType< ElementList, Private::UnRegisterOnDelete > dummy(d); + } + }; //////////////////////////////////////////////////////////////////////////////// Modified: trunk/include/loki/StrongPtr.h =================================================================== --- trunk/include/loki/StrongPtr.h 2009-11-21 10:40:59 UTC (rev 1059) +++ trunk/include/loki/StrongPtr.h 2009-11-21 10:44:08 UTC (rev 1060) @@ -1810,4 +1810,3 @@ #endif // end file guardian - /// specialization of std::less for StroeTracker@Private@Loki@@@std@@@std@@QBEXABV123@@Z |
From: <syn...@us...> - 2009-11-21 10:41:05
|
Revision: 1059 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1059&view=rev Author: syntheticpp Date: 2009-11-21 10:40:59 +0000 (Sat, 21 Nov 2009) Log Message: ----------- add foreach Added Paths: ----------- trunk/include/loki/ForEachType.h Added: trunk/include/loki/ForEachType.h =================================================================== --- trunk/include/loki/ForEachType.h (rev 0) +++ trunk/include/loki/ForEachType.h 2009-11-21 10:40:59 UTC (rev 1059) @@ -0,0 +1,101 @@ + +//////////////////////////////////////////////////////////////////////////////// +// The Loki Library +// Copyright (C) 2009 Andy Balaam +// Copyright (c) 2009 Peter K\xFCmmel +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this +// permission notice appear in supporting documentation. +// The author makes no representations about the +// suitability of this software for any purpose. It is provided "as is" +// without express or implied warranty. +//////////////////////////////////////////////////////////////////////////////// + +#ifndef LOKI_FOR_EACH_TYPE +#define LOKI_FOR_EACH_TYPE + +#include <loki/NullType.h> +#include <loki/Typelist.h> + +namespace Loki +{ + + //////////////////////////////////////////////////////////////////////////////// + // class template ForEachType + // Calls a templated callable for every element of a Typelist + // Supplies an int template parameter for the position in the TypeList. + // Invocation (TList is a typelist): + // ForEachType<TList> dummy(); + // Calls the supplied method during construction of the object dummy. + //////////////////////////////////////////////////////////////////////////////// + + namespace Private + { + // type of recursive function + template <class TList, class Callable> + struct ForEachTypeImpl; + + // Recursion rule + template <class Head, class Tail, class Callable> + struct ForEachTypeImpl<Typelist<Head, Tail>, Callable> + : public ForEachTypeImpl<Tail, Callable> + { + enum { value = 1 + ForEachTypeImpl<Tail, Callable>::value }; + + ForEachTypeImpl( Callable& callable ) : ForEachTypeImpl<Tail, Callable>(callable) + { + callable.operator()<value, Head>(); + } + + }; + + // Recursion end + template <class Head, class Callable> + struct ForEachTypeImpl<Typelist<Head, NullType>, Callable> + { + public: + + enum { value = 0 }; + + ForEachTypeImpl( Callable& callable ) + { + callable.operator()<value, Head>(); + } + }; + + + } + + + struct OrderPolicyForward; + struct OrderPolicyBackward; + + template <class TList, class Callable, class OrderPolicy = OrderPolicyForward> + struct ForEachType; + + template <class TList, class Callable > + struct ForEachType<TList, Callable, OrderPolicyForward> + : public Private::ForEachTypeImpl<typename TL::Reverse<TList>::Result, Callable > + { + ForEachType( Callable& callable ) + : Private::ForEachTypeImpl<typename TL::Reverse<TList>::Result, Callable >( callable ) + { + } + }; + + template <class TList, class Callable > + struct ForEachType<TList, Callable, OrderPolicyBackward> + : public Private::ForEachTypeImpl< TList, Callable > + { + ForEachType( Callable& callable ) + : Private::ForEachTypeImpl< TList, Callable >( callable ) + { + } + }; + + +} + +#endif + Property changes on: trunk/include/loki/ForEachType.h ___________________________________________________________________ Added: svn:eol-style + native This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <syn...@us...> - 2009-11-21 10:31:54
|
Revision: 1058 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1058&view=rev Author: syntheticpp Date: 2009-11-21 10:31:47 +0000 (Sat, 21 Nov 2009) Log Message: ----------- seems this was removed by accident Modified Paths: -------------- trunk/include/loki/StrongPtr.h Modified: trunk/include/loki/StrongPtr.h =================================================================== --- trunk/include/loki/StrongPtr.h 2009-11-20 06:37:12 UTC (rev 1057) +++ trunk/include/loki/StrongPtr.h 2009-11-21 10:31:47 UTC (rev 1058) @@ -1,4 +1,4 @@ -//////////////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// // The Loki Library // Copyright (c) 2006 Rich Sposato // The copyright on this file is protected under the terms of the MIT license. @@ -1778,4 +1778,36 @@ namespace std { //////////////////////////////////////////////////////////////////////////////// - /// specialization of std::less for StroeTracker@Private@Loki@@@std@@@std@@QBEXABV123@@Z |
From: <ric...@us...> - 2009-11-20 06:37:19
|
Revision: 1057 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1057&view=rev Author: rich_sposato Date: 2009-11-20 06:37:12 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Added project to test if compiler implements thread_local correctly. Modified Paths: -------------- trunk/Loki.workspace trunk/Loki_MSVC_9.sln Modified: trunk/Loki.workspace =================================================================== --- trunk/Loki.workspace 2009-11-20 06:35:29 UTC (rev 1056) +++ trunk/Loki.workspace 2009-11-20 06:37:12 UTC (rev 1057) @@ -42,5 +42,6 @@ </Project> <Project filename="test\Visitor\Visitor.cbp" /> <Project filename="test\SafeBits\SafeBits.cbp" /> + <Project filename="test\ThreadLocal\ThreadLocal.cbp" /> </Workspace> </CodeBlocks_workspace_file> Modified: trunk/Loki_MSVC_9.sln =================================================================== --- trunk/Loki_MSVC_9.sln 2009-11-20 06:35:29 UTC (rev 1056) +++ trunk/Loki_MSVC_9.sln 2009-11-20 06:37:12 UTC (rev 1057) @@ -67,6 +67,8 @@ EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SafeBits", "test\SafeBits\SafeBits_MSVC_9.vcproj", "{ECD7ED50-B99D-44BE-BA38-E17D6110C3E5}" EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ThreadLocal", "test\ThreadLocal\ThreadLocal.vcproj", "{27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 @@ -212,6 +214,12 @@ {ECD7ED50-B99D-44BE-BA38-E17D6110C3E5}.Release_MultiThreaded|Win32.Build.0 = Release|Win32 {ECD7ED50-B99D-44BE-BA38-E17D6110C3E5}.Release|Win32.ActiveCfg = Release|Win32 {ECD7ED50-B99D-44BE-BA38-E17D6110C3E5}.Release|Win32.Build.0 = Release|Win32 + {27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}.Debug|Win32.ActiveCfg = Debug|Win32 + {27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}.Debug|Win32.Build.0 = Debug|Win32 + {27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}.Release_MultiThreaded|Win32.ActiveCfg = Release|Win32 + {27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}.Release_MultiThreaded|Win32.Build.0 = Release|Win32 + {27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}.Release|Win32.ActiveCfg = Release|Win32 + {27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}.Release|Win32.Build.0 = Release|Win32 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-20 06:35:37
|
Revision: 1056 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1056&view=rev Author: rich_sposato Date: 2009-11-20 06:35:29 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Added warning to suggest running ThreadLocal test project. Modified Paths: -------------- trunk/include/loki/ThreadLocal.h Modified: trunk/include/loki/ThreadLocal.h =================================================================== --- trunk/include/loki/ThreadLocal.h 2009-11-20 06:33:15 UTC (rev 1055) +++ trunk/include/loki/ThreadLocal.h 2009-11-20 06:35:29 UTC (rev 1056) @@ -20,7 +20,7 @@ // First assume the compiler does allow thread-local storage by #defining the // macro which allows compiler to see the code inside this file. -// Then #undefine the macro for compilers which are known for not supporting +// Then #undef the macro for compilers which are known for not supporting // thread-local storage. #define LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE 1 @@ -59,6 +59,7 @@ #else #warning "Check if your compiler provides thread local storage." + #warning "Run ThreadLocal test project to see if the compiler implements thread_local correctly." #define LOKI_THREAD_LOCAL thread_local #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-20 06:33:24
|
Revision: 1055 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1055&view=rev Author: rich_sposato Date: 2009-11-20 06:33:15 +0000 (Fri, 20 Nov 2009) Log Message: ----------- Added ThreadLocal test project to Loki. Added Paths: ----------- trunk/test/ThreadLocal/ trunk/test/ThreadLocal/ThreadLocal.cbp trunk/test/ThreadLocal/ThreadLocal.vcproj trunk/test/ThreadLocal/main.cpp Added: trunk/test/ThreadLocal/ThreadLocal.cbp =================================================================== --- trunk/test/ThreadLocal/ThreadLocal.cbp (rev 0) +++ trunk/test/ThreadLocal/ThreadLocal.cbp 2009-11-20 06:33:15 UTC (rev 1055) @@ -0,0 +1,46 @@ +<?xml version="1.0" encoding="UTF-8" standalone="yes" ?> +<CodeBlocks_project_file> + <FileVersion major="1" minor="6" /> + <Project> + <Option title="ThreadLocal" /> + <Option pch_mode="2" /> + <Option compiler="gcc" /> + <Build> + <Target title="Debug_GCC"> + <Option output="obj\Debug_GCC\ThreadLocal" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj\Debug_GCC\" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add option="-Wmain" /> + <Add option="-pedantic" /> + <Add option="-W" /> + <Add option="-g" /> + <Add directory="..\..\include" /> + </Compiler> + </Target> + <Target title="Release_GCC"> + <Option output="obj\Release_GCC\ThreadLocal" prefix_auto="1" extension_auto="1" /> + <Option object_output="obj\Release_GCC\" /> + <Option type="1" /> + <Option compiler="gcc" /> + <Compiler> + <Add option="-O2" /> + </Compiler> + <Linker> + <Add option="-s" /> + </Linker> + </Target> + </Build> + <Compiler> + <Add option="-Wall" /> + <Add option="-fexceptions" /> + </Compiler> + <Unit filename="main.cpp" /> + <Extensions> + <code_completion /> + <debugger /> + <lib_finder disable_auto="1" /> + </Extensions> + </Project> +</CodeBlocks_project_file> Added: trunk/test/ThreadLocal/ThreadLocal.vcproj =================================================================== --- trunk/test/ThreadLocal/ThreadLocal.vcproj (rev 0) +++ trunk/test/ThreadLocal/ThreadLocal.vcproj 2009-11-20 06:33:15 UTC (rev 1055) @@ -0,0 +1,188 @@ +<?xml version="1.0" encoding="Windows-1252"?> +<VisualStudioProject + ProjectType="Visual C++" + Version="9.00" + Name="ThreadLocal" + ProjectGUID="{27CB0BB1-1754-46AB-A8C6-697D1B9B9C41}" + RootNamespace="ThreadLocal" + Keyword="Win32Proj" + TargetFrameworkVersion="196613" + > + <Platforms> + <Platform + Name="Win32" + /> + </Platforms> + <ToolFiles> + </ToolFiles> + <Configurations> + <Configuration + Name="Debug|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="0" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="0" + AdditionalIncludeDirectories="../../include" + PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" + StringPooling="true" + MinimalRebuild="true" + BasicRuntimeChecks="3" + RuntimeLibrary="3" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="3" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(ProjectDir)\$(ConfigurationName)\$(ProjectName).exe" + LinkIncremental="2" + GenerateDebugInformation="true" + SubSystem="1" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + <Configuration + Name="Release|Win32" + OutputDirectory="$(SolutionDir)$(ConfigurationName)" + IntermediateDirectory="$(ConfigurationName)" + ConfigurationType="1" + CharacterSet="0" + WholeProgramOptimization="1" + > + <Tool + Name="VCPreBuildEventTool" + /> + <Tool + Name="VCCustomBuildTool" + /> + <Tool + Name="VCXMLDataGeneratorTool" + /> + <Tool + Name="VCWebServiceProxyGeneratorTool" + /> + <Tool + Name="VCMIDLTool" + /> + <Tool + Name="VCCLCompilerTool" + Optimization="2" + EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="../../include" + PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" + StringPooling="true" + RuntimeLibrary="2" + EnableFunctionLevelLinking="true" + UsePrecompiledHeader="0" + WarningLevel="4" + DebugInformationFormat="0" + /> + <Tool + Name="VCManagedResourceCompilerTool" + /> + <Tool + Name="VCResourceCompilerTool" + /> + <Tool + Name="VCPreLinkEventTool" + /> + <Tool + Name="VCLinkerTool" + OutputFile="$(ProjectDir)\$(ConfigurationName)\$(ProjectName).exe" + LinkIncremental="1" + GenerateDebugInformation="true" + SubSystem="1" + OptimizeReferences="2" + EnableCOMDATFolding="2" + TargetMachine="1" + /> + <Tool + Name="VCALinkTool" + /> + <Tool + Name="VCManifestTool" + /> + <Tool + Name="VCXDCMakeTool" + /> + <Tool + Name="VCBscMakeTool" + /> + <Tool + Name="VCFxCopTool" + /> + <Tool + Name="VCAppVerifierTool" + /> + <Tool + Name="VCPostBuildEventTool" + /> + </Configuration> + </Configurations> + <References> + </References> + <Files> + <Filter + Name="Source Files" + Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx" + UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}" + > + <File + RelativePath=".\main.cpp" + > + </File> + </Filter> + </Files> + <Globals> + </Globals> +</VisualStudioProject> Added: trunk/test/ThreadLocal/main.cpp =================================================================== --- trunk/test/ThreadLocal/main.cpp (rev 0) +++ trunk/test/ThreadLocal/main.cpp 2009-11-20 06:33:15 UTC (rev 1055) @@ -0,0 +1,398 @@ +//////////////////////////////////////////////////////////////////////////////// +// +// ThreadLocal test program for The Loki Library +// Copyright (c) 2009 by Richard Sposato +// The copyright on this file is protected under the terms of the MIT license. +// +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this +// permission notice appear in supporting documentation. +// +// The author makes no representations about the suitability of this software +// for any purpose. It is provided "as is" without express or implied warranty. +// +//////////////////////////////////////////////////////////////////////////////// + +// $Id$ + + +// ---------------------------------------------------------------------------- + +#include <loki/ThreadLocal.h> +#include <loki/Threads.h> + +#include <vector> +#include <sstream> +#include <iostream> + + +using namespace ::std; + +#if !defined( NULL ) + #define NULL 0 +#endif + +// define nullptr even though new compilers will have this keyword just so we +// have a consistent and easy way of identifying which uses of 0 mean null. +#if !defined( nullptr ) + #define nullptr NULL +#endif + +#if defined(_WIN32) + + #include <process.h> + #include <windows.h> + + typedef unsigned int ( WINAPI * ThreadFunction_ )( void * ); + + #define LOKI_pthread_t HANDLE + + #define LOKI_pthread_create( handle, attr, func, arg ) \ + ( int )( ( *handle = ( HANDLE ) _beginthreadex ( NULL, 0, ( ThreadFunction_ )func, arg, 0, NULL ) ) == NULL ) + + #define LOKI_pthread_join( thread ) \ + ( ( WaitForSingleObject( ( thread ), INFINITE ) != WAIT_OBJECT_0 ) || !CloseHandle( thread ) ) + +#else + + #define LOKI_pthread_t \ + pthread_t + #define LOKI_pthread_create(handle,attr,func,arg) \ + pthread_create(handle,attr,func,arg) + #define LOKI_pthread_join(thread) \ + pthread_join(thread, NULL) + +#endif + +// ---------------------------------------------------------------------------- + +class Thread +{ +public: + + typedef void * ( * CallFunction )( void * ); + + Thread( CallFunction func, void * parm ) + : pthread_() + , func_( func ) + , parm_( parm ) + { + } + + void AssignTask( CallFunction func, void * parm ) + { + func_ = func; + parm_ = parm; + } + + int Start( void ) + { + return LOKI_pthread_create( &pthread_, NULL, func_, parm_ ); + } + + int WaitForThread( void ) const + { + return LOKI_pthread_join( pthread_ ); + } + +private: + LOKI_pthread_t pthread_; + CallFunction func_; + void * parm_; +}; + +// ---------------------------------------------------------------------------- + +class ThreadPool +{ +public: + ThreadPool( void ) : m_threads() + { + } + + void Create( size_t threadCount, Thread::CallFunction function ) + { + for( size_t ii = 0; ii < threadCount; ii++ ) + { + stringstream buffer; + buffer << "Creating thread " << ii << endl; + cout << buffer.rdbuf(); + Thread * thread = new Thread( function, + reinterpret_cast< void * >( ii + 1 ) ); + m_threads.push_back( thread ); + } + } + + void Start( void ) + { + for ( size_t ii = 0; ii < m_threads.size(); ii++ ) + { + stringstream buffer; + buffer << "Starting thread " << ii << endl; + cout << buffer.rdbuf(); + m_threads.at( ii )->Start(); + } + } + + void Join( void ) const + { + for ( size_t ii = 0; ii < m_threads.size(); ii++ ) + m_threads.at( ii )->WaitForThread(); + } + + ~ThreadPool( void ) + { + for ( size_t ii = 0; ii < m_threads.size(); ii++ ) + { + delete m_threads.at(ii); + } + } + +private: + typedef std::vector< Thread * > Threads; + + Threads m_threads; +}; + +// ---------------------------------------------------------------------------- + +typedef ::std::vector< unsigned int > IntVector; + +static LOKI_THREAD_LOCAL unsigned int StandaloneStaticValue = 0; + +static const unsigned int ThreadCount = 4; + +// ---------------------------------------------------------------------------- + +IntVector & GetIntVector( void ) +{ + unsigned int v = 0; + static IntVector addresses( ThreadCount, v ); + return addresses; +} + +// ---------------------------------------------------------------------------- + +void * AddToIntVector( void * p ) +{ + assert( 0 == StandaloneStaticValue ); + const unsigned int ii = reinterpret_cast< unsigned int >( p ); + assert( 0 < ii ); + assert( ii < ThreadCount + 1 ); + StandaloneStaticValue = ii; + IntVector & v = GetIntVector(); + v[ ii - 1 ] = StandaloneStaticValue; + assert( ii == StandaloneStaticValue ); + assert( v[ ii - 1 ] == StandaloneStaticValue ); + return nullptr; +} + +// ---------------------------------------------------------------------------- + +bool TestThreadLocalStaticValue( void ) +{ + assert( StandaloneStaticValue == 0 ); + { + ThreadPool pool; + pool.Create( ThreadCount, &AddToIntVector ); + pool.Start(); + pool.Join(); + } + + bool allDifferent = true; + IntVector & v = GetIntVector(); + for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 ) + { + const unsigned int v1 = v[ i1 ]; + for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 ) + { + const unsigned int v2 = v[ i2 ]; + if ( v1 == v2 ) + { + allDifferent = false; + break; + } + } + if ( !allDifferent ) + break; + } + assert( StandaloneStaticValue == 0 ); + + return allDifferent; +} + +// ---------------------------------------------------------------------------- + +unsigned int & GetFunctionThreadLocalValue( void ) +{ + static LOKI_THREAD_LOCAL unsigned int FunctionStaticValue = 0; + return FunctionStaticValue; +} + +// ---------------------------------------------------------------------------- + +void * ChangeFunctionStaticValue( void * p ) +{ + unsigned int & thatValue = GetFunctionThreadLocalValue(); + assert( 0 == thatValue ); + const unsigned int ii = reinterpret_cast< unsigned int >( p ); + assert( 0 < ii ); + assert( ii < ThreadCount + 1 ); + thatValue = ii + ThreadCount; + IntVector & v = GetIntVector(); + v[ ii - 1 ] = thatValue + ThreadCount; + assert( ii + ThreadCount == thatValue ); + assert( v[ ii - 1 ] == thatValue + ThreadCount ); + return nullptr; +} + +// ---------------------------------------------------------------------------- + +bool TestThreadLocalFunctionStaticValue( void ) +{ + assert( GetFunctionThreadLocalValue() == 0 ); + + IntVector & v = GetIntVector(); + for ( unsigned int i0 = 0; i0 < v.size(); ++i0 ) + { + v[ i0 ] = 0; + } + + { + ThreadPool pool; + pool.Create( ThreadCount, &ChangeFunctionStaticValue ); + pool.Start(); + pool.Join(); + } + + bool allDifferent = true; + for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 ) + { + const unsigned int v1 = v[ i1 ]; + for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 ) + { + const unsigned int v2 = v[ i2 ]; + if ( v1 == v2 ) + { + allDifferent = false; + break; + } + } + if ( !allDifferent ) + break; + } + assert( GetFunctionThreadLocalValue() == 0 ); + + return allDifferent; +} + +// ---------------------------------------------------------------------------- + +class ThreadAware +{ +public: + + static inline void SetValue( unsigned int value ) { ClassThreadLocal = value; } + + static inline unsigned int GetValue( void ) { return ClassThreadLocal; } + +private: + + static LOKI_THREAD_LOCAL unsigned int ClassThreadLocal; + +}; + +LOKI_THREAD_LOCAL unsigned int ThreadAware::ClassThreadLocal = 0; + +// ---------------------------------------------------------------------------- + +void * ChangeClassStaticValue( void * p ) +{ + assert( ThreadAware::GetValue() == 0 ); + const unsigned int ii = reinterpret_cast< unsigned int >( p ); + assert( 0 < ii ); + assert( ii < ThreadCount + 1 ); + ThreadAware::SetValue( ii + 2 * ThreadCount ); + IntVector & v = GetIntVector(); + v[ ii - 1 ] = ThreadAware::GetValue(); + assert( v[ ii - 1 ] == ThreadAware::GetValue() ); + assert( ThreadAware::GetValue() == ii + 2 * ThreadCount ); + return nullptr; +} + +// ---------------------------------------------------------------------------- + +bool TestThreadLocalClassStaticValue( void ) +{ + assert( ThreadAware::GetValue() == 0 ); + + IntVector & v = GetIntVector(); + for ( unsigned int i0 = 0; i0 < v.size(); ++i0 ) + { + v[ i0 ] = 0; + } + + { + ThreadPool pool; + pool.Create( ThreadCount, &ChangeClassStaticValue ); + pool.Start(); + pool.Join(); + } + + bool allDifferent = true; + for ( unsigned int i1 = 0; i1 < ThreadCount - 1; ++i1 ) + { + const unsigned int v1 = v[ i1 ]; + for ( unsigned int i2 = i1 + 1; i2 < ThreadCount; ++i2 ) + { + const unsigned int v2 = v[ i2 ]; + if ( v1 == v2 ) + { + allDifferent = false; + break; + } + } + if ( !allDifferent ) + break; + } + assert( ThreadAware::GetValue() == 0 ); + + return allDifferent; +} + +// ---------------------------------------------------------------------------- + +int main( int argc, const char * const argv[] ) +{ + bool okay = true; + cout << "Starting ThreadLocal tests." << endl; + cout << "If any tests fail, or any assertions fail," << endl + << "then your compiler does not implement thread_local storage correctly." << endl; + + cout << endl << "Testing static thread_local storage inside classes." << endl; + okay = TestThreadLocalClassStaticValue(); + if ( okay ) + cout << "Your compiler correctly implements thread_local storage for class static values." << endl; + else + cout << "Your compiler does not properly implement thread_local storage for class static values." << endl; + + cout << endl << "Testing static thread_local storage inside functions." << endl; + okay = TestThreadLocalFunctionStaticValue(); + if ( okay ) + cout << "Your compiler correctly implements thread_local storage for function static values." << endl; + else + cout << "Your compiler does not properly implement thread_local storage for function static values." << endl; + + cout << endl << "Testing standalone static thread_local storage." << endl; + okay = TestThreadLocalStaticValue(); + if ( okay ) + cout << "Your compiler correctly implements thread_local storage for standalone static values." << endl; + else + cout << "Your compiler does not properly implement thread_local storage for standalone static values." << endl; + + ::system( "pause" ); + return 0; +} + +// ---------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-14 07:12:53
|
Revision: 1054 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1054&view=rev Author: rich_sposato Date: 2009-11-14 07:12:39 +0000 (Sat, 14 Nov 2009) Log Message: ----------- Added include statement. Removed const declaration. Modified Paths: -------------- trunk/include/loki/CachedFactory.h Modified: trunk/include/loki/CachedFactory.h =================================================================== --- trunk/include/loki/CachedFactory.h 2009-11-10 19:27:20 UTC (rev 1053) +++ trunk/include/loki/CachedFactory.h 2009-11-14 07:12:39 UTC (rev 1054) @@ -4,16 +4,16 @@ // // Code covered by the MIT License // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The authors make no representations about the suitability of this software // for any purpose. It is provided "as is" without express or implied warranty. // // This code DOES NOT accompany the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design +// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design // Patterns Applied". Copyright (c) 2001. Addison-Wesley. // //////////////////////////////////////////////////////////////////////////////// @@ -22,6 +22,7 @@ // $Id$ +#include <time.h> ///< For clock_t definition. #include <functional> #include <algorithm> #include <iostream> @@ -47,7 +48,7 @@ * \ingroup FactoriesGroup * \brief CachedFactory provides an extension of a Factory with caching * support. - * + * * Once used objects are returned to the CachedFactory that manages its * destruction. * If your code uses lots of "long to construct/destruct objects" using the @@ -64,11 +65,11 @@ * \class SimplePointer * \ingroup EncapsulationPolicyCachedFactoryGroup * \brief No encaspulation : returns the pointer - * + * * This implementation does not make any encapsulation. * It simply returns the object's pointer. */ - template<class AbstractProduct> + template<class AbstractProduct> class SimplePointer { protected: @@ -77,7 +78,7 @@ { return pProduct; } - + AbstractProduct* release(ProductReturn &pProduct) { AbstractProduct* pPointer(pProduct); @@ -91,7 +92,7 @@ * \defgroup CreationPolicyCachedFactoryGroup Creation policies * \ingroup CachedFactoryGroup * \brief Defines a way to limit the creation operation. - * + * * For instance one may want to be alerted (Exception) when * - Cache has created a more than X object within the last x seconds * - Cache creation rate has increased dramatically @@ -102,7 +103,7 @@ * \class NeverCreate * \ingroup CreationPolicyCachedFactoryGroup * \brief Never allows creation. Testing purposes only. - * + * * Using this policy will throw an exception. */ class NeverCreate @@ -112,22 +113,22 @@ { const char* what() const throw() { return "NeverFetch Policy : No Fetching allowed"; } }; - + bool canCreate() { throw Exception(); } - + void onCreate(){} void onDestroy(){} const char* name(){return "never";} }; - + /** * \class AlwaysCreate * \ingroup CreationPolicyCachedFactoryGroup * \brief Always allows creation. - * + * * Doesn't limit the creation in any way */ class AlwaysCreate @@ -148,7 +149,7 @@ * \class RateLimitedCreation * \ingroup CreationPolicyCachedFactoryGroup * \brief Limit in rate. - * + * * This implementation will prevent from Creating more than maxCreation objects * within byTime ms by throwing an exception. * Could be usefull to detect prevent loads (http connection for instance). @@ -167,7 +168,7 @@ unsigned maxCreation; clock_t timeValidity; clock_t lastUpdate; - + void cleanVector() { using namespace std; @@ -193,7 +194,7 @@ } lastUpdate = currentTime; } -#ifdef DO_EXTRA_LOKI_TESTS +#ifdef DO_EXTRA_LOKI_TESTS void displayVector() { std::cout << "Vector : "; @@ -204,12 +205,12 @@ protected: RateLimitedCreation() : maxCreation(10), timeValidity(CLOCKS_PER_SEC), lastUpdate(clock()) {} - + struct Exception : public std::exception { const char* what() const throw() { return "RateLimitedCreation Policy : Exceeded the authorized creation rate"; } }; - + bool canCreate() { cleanVector(); @@ -223,7 +224,7 @@ { m_vTimes.push_back(clock()); } - + void onDestroy() { } @@ -239,12 +240,12 @@ D( std::cout << "Setting no more than "<< maxCreation <<" creation within " << this->timeValidity <<" ms"<< std::endl; ) } }; - + /** * \class AmountLimitedCreation * \ingroup CreationPolicyCachedFactoryGroup * \brief Limit by number of objects - * + * * This implementation will prevent from Creating more than maxCreation objects * within byTime ms by calling eviction policy. * Use the setRate method to set the rate parameters. @@ -255,11 +256,11 @@ private: unsigned maxCreation; unsigned created; - + protected: AmountLimitedCreation() : maxCreation(10), created(0) {} - + bool canCreate() { return !(created>=maxCreation); @@ -269,7 +270,7 @@ { ++created; } - + void onDestroy() { --created; @@ -284,7 +285,7 @@ D( std::cout << "Setting no more than " << maxCreation <<" creation" << std::endl; ) } }; - + /** * \defgroup EvictionPolicyCachedFactoryGroup Eviction policies * \ingroup CachedFactoryGroup @@ -316,7 +317,7 @@ typedef typename SwappedHitMap::iterator SwappedHitMapItr; protected: HitMap m_mHitCount; - + // This function sorts the map according to the score // and returns the lower bound of the sorted container DT& getLowerBound(){ @@ -330,15 +331,15 @@ return (*copyMap.begin()).second; } }; - + /** * \class EvictLRU * \ingroup EvictionPolicyCachedFactoryGroup * \brief Evicts least accessed objects first. - * + * * Implementation of the Least recent used algorithm as * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms . - * + * * WARNING : If an object is heavily fetched * (more than ULONG_MAX = UINT_MAX = 4294967295U) * it could unfortunately be removed from the cache. @@ -353,20 +354,20 @@ private: typedef EvictionHelper< ST , DT > EH; protected: - + virtual ~EvictLRU(){} - + // OnStore initialize the counter for the new key // If the key already exists, the counter is reseted void onCreate(const DT& key) { EH::m_mHitCount[key] = 0; } - + void onFetch(const DT&) { } - + // onRelease increments the hit counter associated with the object void onRelease(const DT& key) { @@ -377,7 +378,7 @@ { EH::m_mHitCount.erase(key); } - + // this function is implemented in Cache and redirected // to the Storage Policy virtual void remove(DT const key)=0; @@ -389,15 +390,15 @@ } const char* name(){return "LRU";} }; - + /** * \class EvictAging * \ingroup EvictionPolicyCachedFactoryGroup * \brief LRU aware of the time span of use - * + * * Implementation of the Aging algorithm as * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms . - * + * * This method is much more costly than evict LRU so * if you need extreme performance consider switching to EvictLRU */ @@ -414,7 +415,7 @@ typedef EvictionHelper< ST, DT > EH; typedef typename EH::HitMap HitMap; typedef typename EH::HitMapItr HitMapItr; - + // update the counter template<class T> struct updateCounter : public std::unary_function<T, void> { @@ -432,15 +433,15 @@ protected: EvictAging(){} virtual ~EvictAging(){} - + // OnStore initialize the counter for the new key // If the key already exists, the counter is reseted void onCreate(const DT& key){ EH::m_mHitCount[key] = 0; } - + void onFetch(const DT&){} - + // onRelease increments the hit counter associated with the object // Updating every counters by iterating over the map // If the key is the key of the fetched object : @@ -451,7 +452,7 @@ { std::for_each(EH::m_mHitCount.begin(), EH::m_mHitCount.end(), updateCounter< typename HitMap::value_type >(key)); } - + void onDestroy(const DT& key) { EH::m_mHitCount.erase(key); @@ -468,12 +469,12 @@ } const char* name(){return "LRU with aging";} }; - + /** * \class EvictRandom * \ingroup EvictionPolicyCachedFactoryGroup * \brief Evicts a random object - * + * * Implementation of the Random algorithm as * described in http://en.wikipedia.org/wiki/Page_replacement_algorithms . */ @@ -490,24 +491,24 @@ typedef typename std::vector< DT >::iterator iterator; protected: - + virtual ~EvictRandom(){} - + void onCreate(const DT&){ } - + void onFetch(const DT& ){ } void onRelease(const DT& key){ m_vKeys.push_back(key); } - + void onDestroy(const DT& key){ using namespace std; m_vKeys.erase(remove_if(m_vKeys.begin(), m_vKeys.end(), bind2nd(equal_to< DT >(), key)), m_vKeys.end()); } - + // Implemented in Cache and redirected to the Storage Policy virtual void remove(DT const key)=0; @@ -526,7 +527,7 @@ * \defgroup StatisticPolicyCachedFactoryGroup Statistic policies * \ingroup CachedFactoryGroup * \brief Gathers information about the cache. - * + * * For debugging purpose this policy proposes to gather informations * about the cache. This could be useful to determine whether the cache is * mandatory or if the policies are well suited to the application. @@ -536,7 +537,7 @@ * \ingroup StatisticPolicyCachedFactoryGroup * \brief Do nothing * - * Should be used in release code for better performances + * Should be used in release code for better performances */ class NoStatisticPolicy { @@ -548,7 +549,7 @@ void onDestroy(){} const char* name(){return "no";} }; - + /** * \class SimpleStatisticPolicy * \ingroup StatisticPolicyCachedFactoryGroup @@ -572,7 +573,7 @@ SimpleStatisticPolicy() : allocated(0), created(0), hit(0), out(0), fetched(0) { } - + void onDebug() { using namespace std; @@ -592,7 +593,7 @@ } cout << endl; } - + void onFetch() { ++fetched; @@ -623,8 +624,8 @@ unsigned getAllocated(){return allocated;} unsigned getOut(){return out;} unsigned getDestroyed(){return created-allocated;} - }; - + }; + /////////////////////////////////////////////////////////////////////////// // Cache Factory definition /////////////////////////////////////////////////////////////////////////// @@ -633,16 +634,16 @@ public: const char* what() const throw() { return "Internal Cache Error"; } }; - + /** * \class CachedFactory * \ingroup CachedFactoryGroup * \brief Factory with caching support - * + * * This class acts as a Factory (it creates objects) * but also keeps the already created objects to prevent * long constructions time. - * + * * Note this implementation do not retain ownership. */ template @@ -657,7 +658,7 @@ template<typename, class> class FactoryErrorPolicy = DefaultFactoryError, class ObjVector = std::vector<AbstractProduct*> > - class CachedFactory : + class CachedFactory : protected EncapsulationPolicy<AbstractProduct>, public CreationPolicy, public StatisticPolicy, EvictionPolicy< AbstractProduct * , unsigned > { @@ -669,7 +670,7 @@ typedef CreationPolicy CP; typedef StatisticPolicy SP; typedef EvictionPolicy< AbstractProduct* , unsigned > EP; - + typedef typename Impl::Parm1 Parm1; typedef typename Impl::Parm2 Parm2; typedef typename Impl::Parm3 Parm3; @@ -685,14 +686,14 @@ typedef typename Impl::Parm13 Parm13; typedef typename Impl::Parm14 Parm14; typedef typename Impl::Parm15 Parm15; - + public: typedef typename NP::ProductReturn ProductReturn; private: typedef Key< Impl, IdentifierType > MyKey; typedef std::map< MyKey, ObjVector > KeyToObjVectorMap; typedef std::map< AbstractProduct*, MyKey > FetchedObjToKeyMap; - + MyFactory factory; KeyToObjVectorMap fromKeyToObjVector; FetchedObjToKeyMap providedObjects; @@ -702,7 +703,7 @@ return fromKeyToObjVector[key]; } - AbstractProduct* const getPointerToObjectInContainer(ObjVector &entry) + AbstractProduct* getPointerToObjectInContainer(ObjVector &entry) { if(entry.empty()) // No object available { // the object will be created in the calling function. @@ -718,7 +719,7 @@ return pObject; } } - + bool shouldCreateObject(AbstractProduct * const pProduct){ if(pProduct!=NULL) // object already exists return false; @@ -726,40 +727,40 @@ EP::evict(); // calling Eviction Policy to clean up return true; } - + void ReleaseObjectFromContainer(ObjVector &entry, AbstractProduct * const object) { entry.push_back(object); } - + void onFetch(AbstractProduct * const pProduct) { SP::onFetch(); EP::onFetch(pProduct); ++outObjects; } - + void onRelease(AbstractProduct * const pProduct) { SP::onRelease(); EP::onRelease(pProduct); --outObjects; } - + void onCreate(AbstractProduct * const pProduct) { CP::onCreate(); SP::onCreate(); EP::onCreate(pProduct); } - + void onDestroy(AbstractProduct * const pProduct) { CP::onDestroy(); SP::onDestroy(); EP::onDestroy(pProduct); } - + // delete the object template<class T> struct deleteObject : public std::unary_function<T, void> { @@ -779,7 +780,7 @@ template<class T> struct deleteMapKeys : public std::unary_function<T, void> { void operator()(T x){ delete x.first; } - }; + }; protected: virtual void remove(AbstractProduct * const pProduct) @@ -834,23 +835,23 @@ ); } } - + /////////////////////////////////// // Acts as the proxy pattern and // // forwards factory methods // /////////////////////////////////// - + bool Register(const IdentifierType& id, ProductCreator creator) { return factory.Register(id, creator); } - + template <class PtrObj, typename CreaFn> bool Register(const IdentifierType& id, const PtrObj& p, CreaFn fn) { return factory.Register(id, p, fn); } - + bool Unregister(const IdentifierType& id) { return factory.Unregister(id); @@ -875,7 +876,7 @@ providedObjects[pProduct] = key; return NP::encapsulate(pProduct); } - + ProductReturn CreateObject(const IdentifierType& id, Parm1 p1) { @@ -1020,7 +1021,7 @@ providedObjects[pProduct] = key; return NP::encapsulate(pProduct); } - + ProductReturn CreateObject(const IdentifierType& id, Parm1 p1, Parm2 p2, Parm3 p3, Parm4 p4, Parm5 p5, Parm6 p6, Parm7 p7, Parm8 p8, Parm9 p9,Parm10 p10) @@ -1147,7 +1148,7 @@ ReleaseObjectFromContainer(getContainerFromKey((*itr).second), pProduct); providedObjects.erase(itr); } - + /// display the cache configuration void displayCacheType() { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-10 19:27:34
|
Revision: 1053 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1053&view=rev Author: rich_sposato Date: 2009-11-10 19:27:20 +0000 (Tue, 10 Nov 2009) Log Message: ----------- Added tests for dynamic-casting with SmartPtr and StrongPtr. Modified Paths: -------------- trunk/test/SmartPtr/main.cpp trunk/test/SmartPtr/strong.cpp Modified: trunk/test/SmartPtr/main.cpp =================================================================== --- trunk/test/SmartPtr/main.cpp 2009-11-10 19:22:16 UTC (rev 1052) +++ trunk/test/SmartPtr/main.cpp 2009-11-10 19:27:20 UTC (rev 1053) @@ -1,12 +1,12 @@ //////////////////////////////////////////////////////////////////////////////// // Test program for The Loki Library // Copyright (c) 2006 Richard Sposato -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. -// The authors make no representations about the -// suitability of this software for any purpose. It is provided "as is" +// The authors make no representations about the +// suitability of this software for any purpose. It is provided "as is" // without express or implied warranty. //////////////////////////////////////////////////////////////////////////////// @@ -35,6 +35,7 @@ extern void DoStrongConstTests( void ); extern void DoStrongForwardReferenceTest( void ); extern void DoStrongCompareTests( void ); +extern void DoStrongPtrDynamicCastTests( void ); extern void DoLockedPtrTest( void ); extern void DoLockedStorageTest( void ); @@ -1113,7 +1114,123 @@ //p6 = p5; } +// ---------------------------------------------------------------------------- +namespace +{ + + class Feline + { + public: + virtual ~Feline() {} + }; + + class Lion : public Feline + { + public: + virtual ~Lion() {} + }; + + class Tiger : public Feline + { + public: + virtual ~Tiger() {} + }; + + class Dog + { + public: + virtual ~Dog() {} + }; + +}; + +// ---------------------------------------------------------------------------- + +void DoSmartPtrDynamicCastTests( void ) +{ + typedef ::Loki::SmartPtr< Feline > FelinePtr; + typedef ::Loki::SmartPtr< Lion > LionPtr; + typedef ::Loki::SmartPtr< Tiger > TigerPtr; + typedef ::Loki::SmartPtr< Dog > DogPtr; + + Feline * feline = new Lion; + Lion * lion = new Lion; + Tiger * tiger = new Tiger; + Dog * dog = new Dog; + + FelinePtr pFeline( feline ); + LionPtr pLion( lion ); + TigerPtr pTiger( tiger ); + DogPtr pDog( dog ); + + // This is legal because C++ allows an automatic down-cast to public base class. + pFeline = pLion; + +#ifdef CHECK_TYPE_CAST + pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr +#endif // CHECK_TYPE_CAST + + assert( pFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pLion ); + assert( !pDog ); + + feline = new Lion; + lion = new Lion; + tiger = new Tiger; + dog = new Dog; + + // Now do tests when converting from const pointers. + const FelinePtr pcFeline( feline ); + const LionPtr pcLion( lion ); + const TigerPtr pcTiger( tiger ); + const DogPtr pcDog( dog ); + + assert( pcFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pcLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pcDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pcLion ); + assert( !pDog ); +} + +// ---------------------------------------------------------------------------- + int main( int argc, const char * argv[] ) { bool doThreadTest = false; @@ -1146,6 +1263,8 @@ DoConstConversionTests(); DoOwnershipConversionTests(); DoInheritanceConversionTests(); + DoSmartPtrDynamicCastTests(); + DoStrongPtrDynamicCastTests(); #if defined (LOKI_OBJECT_LEVEL_THREADING) || defined (LOKI_CLASS_LEVEL_THREADING) if ( doThreadTest ) @@ -1176,15 +1295,15 @@ }; typedef Loki::SmartPtr -< +< BaseClass, RefCounted, DisallowConversion, - AssertCheck, DefaultSPStorage, DontPropagateConst -> + AssertCheck, DefaultSPStorage, DontPropagateConst +> Ptr; bool Compare( const Ptr&, const Ptr&) { - return true; + return true; } void friend_handling() Modified: trunk/test/SmartPtr/strong.cpp =================================================================== --- trunk/test/SmartPtr/strong.cpp 2009-11-10 19:22:16 UTC (rev 1052) +++ trunk/test/SmartPtr/strong.cpp 2009-11-10 19:27:20 UTC (rev 1053) @@ -1186,37 +1186,316 @@ // ---------------------------------------------------------------------------- +namespace +{ + class Feline + { + public: + virtual ~Feline() {} + }; + + class Lion : public Feline + { + public: + virtual ~Lion() {} + }; + + class Tiger : public Feline + { + public: + virtual ~Tiger() {} + }; + + class Dog + { + public: + virtual ~Dog() {} + }; + +}; + +// ---------------------------------------------------------------------------- + +void DoStrongPtrDynamicCastTests( void ) +{ + typedef ::Loki::StrongPtr< Feline, true, ::Loki::TwoRefCounts > FelineCountPtr; + typedef ::Loki::StrongPtr< Tiger, true, ::Loki::TwoRefCounts > TigerCountPtr; + typedef ::Loki::StrongPtr< Lion, true, ::Loki::TwoRefCounts > LionCountPtr; + typedef ::Loki::StrongPtr< Dog, true, ::Loki::TwoRefCounts > DogCountPtr; + + typedef ::Loki::StrongPtr< Feline, true, ::Loki::LockableTwoRefCounts > FelineLockPtr; + typedef ::Loki::StrongPtr< Tiger, true, ::Loki::LockableTwoRefCounts > TigerLockPtr; + typedef ::Loki::StrongPtr< Lion, true, ::Loki::LockableTwoRefCounts > LionLockPtr; + typedef ::Loki::StrongPtr< Dog, true, ::Loki::LockableTwoRefCounts > DogLockPtr; + + typedef ::Loki::StrongPtr< Feline, true, ::Loki::TwoRefLinks > FelineLinksPtr; + typedef ::Loki::StrongPtr< Tiger, true, ::Loki::TwoRefLinks > TigerLinksPtr; + typedef ::Loki::StrongPtr< Lion, true, ::Loki::TwoRefLinks > LionLinksPtr; + typedef ::Loki::StrongPtr< Dog, true, ::Loki::TwoRefLinks > DogLinksPtr; + + { + Feline * feline = new Lion; + Tiger * tiger = new Tiger; + Lion * lion = new Lion; + Dog * dog = new Dog; + + FelineCountPtr pFeline( feline ); + TigerCountPtr pTiger( tiger ); + LionCountPtr pLion( lion ); + DogCountPtr pDog( dog ); + + // This is legal because C++ allows an automatic down-cast to public base class. + pFeline = pLion; + +#ifdef CHECK_TYPE_CAST + pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr +#endif // CHECK_TYPE_CAST + + assert( pFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pLion ); + assert( !pDog ); + + feline = new Lion; + lion = new Lion; + tiger = new Tiger; + dog = new Dog; + + // Now do tests when converting from const pointers. + const FelineCountPtr pcFeline( feline ); + const TigerCountPtr pcTiger( tiger ); + const LionCountPtr pcLion( lion ); + const DogCountPtr pcDog( dog ); + + assert( pcFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pcLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pcDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pcLion ); + assert( !pDog ); + } + + { + Feline * feline = new Lion; + Tiger * tiger = new Tiger; + Lion * lion = new Lion; + Dog * dog = new Dog; + + FelineLockPtr pFeline( feline ); + TigerLockPtr pTiger( tiger ); + LionLockPtr pLion( lion ); + DogLockPtr pDog( dog ); + + // This is legal because C++ allows an automatic down-cast to public base class. + pFeline = pLion; + +#ifdef CHECK_TYPE_CAST + pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr +#endif // CHECK_TYPE_CAST + + assert( pFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pLion ); + assert( !pDog ); + + feline = new Lion; + tiger = new Tiger; + lion = new Lion; + dog = new Dog; + + // Now do tests when converting from const pointers. + const FelineLockPtr pcFeline( feline ); + const TigerLockPtr pcTiger( tiger ); + const LionLockPtr pcLion( lion ); + const DogLockPtr pcDog( dog ); + + assert( pcFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pcLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pcDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pcLion ); + assert( !pDog ); + } + + { + Feline * feline = new Lion; + Tiger * tiger = new Tiger; + Lion * lion = new Lion; + Dog * dog = new Dog; + + FelineLinksPtr pFeline( feline ); + TigerLinksPtr pTiger( tiger ); + LionLinksPtr pLion( lion ); + DogLinksPtr pDog( dog ); + + // This is legal because C++ allows an automatic down-cast to public base class. + pFeline = pLion; + +#ifdef CHECK_TYPE_CAST + pLion = pFeline; // Fails as the compiler cannot convert pointers in SmartPtr +#endif // CHECK_TYPE_CAST + + assert( pFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pFeline ); + assert( pLion ); + assert( pLion == pFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pLion ); + assert( !pDog ); + + feline = new Lion; + tiger = new Tiger; + lion = new Lion; + dog = new Dog; + + // Now do tests when converting from const pointers. + const FelineLinksPtr pcFeline( feline ); + const TigerLinksPtr pcTiger( tiger ); + const LionLinksPtr pcLion( lion ); + const DogLinksPtr pcDog( dog ); + + assert( pcFeline ); + // Can up-cast from feline to lion only if the feline is a lion. + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to tiger since although these are both types of felines, + // they are not related to one another. + pTiger.DynamicCastFrom( pcLion ); + assert( !pTiger ); + + // Can't cast from dog to lion since a dog is not a type of feline. + pLion.DynamicCastFrom( pcDog ); + assert( !pLion ); + + pLion.DynamicCastFrom( pcFeline ); + assert( pLion ); + assert( pLion == pcFeline ); + + // Can't cast from lion to dog since these animal types are not related. + pDog.DynamicCastFrom( pcLion ); + assert( !pDog ); + } +} + +// ---------------------------------------------------------------------------- + + // GCC bug // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38579 struct Policy { protected: - Policy() {} - Policy(const Policy&) {} - int i; + Policy() {} + Policy(const Policy&) {} + int i; }; template<int I, class P> struct BugGcc : - //protected P - public P + //protected P + public P { - BugGcc() {} + BugGcc() {} - template<int I2, class P2> - BugGcc(const BugGcc<I2, P2>& t) : P(t) {} + template<int I2, class P2> + BugGcc(const BugGcc<I2, P2>& t) : P(t) {} }; void foo() { - BugGcc<0, Policy> f1; - BugGcc<1, Policy> f2(f1); + BugGcc<0, Policy> f1; + BugGcc<1, Policy> f2(f1); - // Policy members are still not public, - // this will not compile: - //int i = f1.i; + // Policy members are still not public, + // this will not compile: + //int i = f1.i; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-10 19:22:24
|
Revision: 1052 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1052&view=rev Author: rich_sposato Date: 2009-11-10 19:22:16 +0000 (Tue, 10 Nov 2009) Log Message: ----------- Implemented patch 2893162 to allow dynamic-casting with SmartPtr and StrongPtr. Modified Paths: -------------- trunk/include/loki/SmartPtr.h trunk/include/loki/StrongPtr.h trunk/src/StrongPtr.cpp Modified: trunk/include/loki/SmartPtr.h =================================================================== --- trunk/include/loki/SmartPtr.h 2009-11-02 22:45:51 UTC (rev 1051) +++ trunk/include/loki/SmartPtr.h 2009-11-10 19:22:16 UTC (rev 1052) @@ -194,9 +194,9 @@ // Destroys the data stored // (Destruction might be taken over by the OwnershipPolicy) - // - // If your compiler gives you a warning in this area while - // compiling the tests, it is on purpose, please ignore it. + // + // If your compiler gives you a warning in this area while + // compiling the tests, it is on purpose, please ignore it. void Destroy() { delete pointee_; @@ -1172,6 +1172,45 @@ typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg; #endif + /// SmartPtr uses this helper class to specify the dynamic-caster constructor. + class DynamicCastHelper {}; + + /// Private constructor is only used for dynamic-casting. + template + < + typename T1, + template < class > class OP1, + class CP1, + template < class > class KP1, + template < class > class SP1, + template < class > class CNP1 + > + SmartPtr( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs, const DynamicCastHelper & helper ) + { + (void)helper; // do void cast to remove compiler warning. + // Dynamic casting from T1 to T and saving result in `this''s pointer + PointerType p = dynamic_cast< PointerType >( GetImplRef( rhs ) ); + GetImplRef( *this ) = OP::Clone( p ); + } + + /// Private constructor is only used for dynamic-casting. + template + < + typename T1, + template < class > class OP1, + class CP1, + template < class > class KP1, + template < class > class SP1, + template < class > class CNP1 + > + SmartPtr( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs, const DynamicCastHelper & helper ) + { + (void)helper; // do void cast to remove compiler warning. + // Dynamic casting from T1 to T and saving result in `this''s pointer + PointerType p = dynamic_cast< PointerType >( GetImplRef( rhs ) ); + GetImplRef( *this ) = OP::Clone( p ); + } + public: SmartPtr() @@ -1206,7 +1245,9 @@ > SmartPtr(const SmartPtr<T1, OP1, CP1, KP1, SP1, CNP1 >& rhs) : SP(rhs), OP(rhs), KP(rhs), CP(rhs) - { GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); } + { + GetImplRef(*this) = OP::Clone(GetImplRef(rhs)); + } template < @@ -1285,6 +1326,40 @@ } } + /// Dynamically-casts parameter pointer to the type specified by this SmartPtr type. + template + < + typename T1, + template < class > class OP1, + class CP1, + template < class > class KP1, + template < class > class SP1, + template < class > class CNP1 + > + SmartPtr & DynamicCastFrom( const SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) + { + SmartPtr temp( rhs, DynamicCastHelper() ); + temp.Swap( *this ); + return *this; + } + + /// Dynamically-casts parameter pointer to the type specified by this SmartPtr type. + template + < + typename T1, + template < class > class OP1, + class CP1, + template < class > class KP1, + template < class > class SP1, + template < class > class CNP1 + > + SmartPtr & DynamicCastFrom( SmartPtr< T1, OP1, CP1, KP1, SP1, CNP1 > & rhs ) + { + SmartPtr temp( rhs, DynamicCastHelper() ); + temp.Swap( *this ); + return *this; + } + #ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND // old non standard in class definition of friends Modified: trunk/include/loki/StrongPtr.h =================================================================== --- trunk/include/loki/StrongPtr.h 2009-11-02 22:45:51 UTC (rev 1051) +++ trunk/include/loki/StrongPtr.h 2009-11-10 19:22:16 UTC (rev 1052) @@ -564,6 +564,8 @@ Increment( strong ); } + TwoRefCounts( const TwoRefCounts & rhs, bool isNull, bool strong ); + /** The destructor does not need to do anything since the call to ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which this dtor would have done. @@ -664,6 +666,24 @@ Increment( strong ); } + LockableTwoRefCounts( const LockableTwoRefCounts & rhs, bool isNull, bool strong ) : + m_counts( ( isNull ) ? NULL : rhs.m_counts ) + { + if ( isNull ) + { + void * temp = ThreadSafePointerAllocator::operator new( + sizeof(Loki::Private::LockableTwoRefCountInfo) ); +#ifdef DO_EXTRA_LOKI_TESTS + assert( temp != 0 ); +#endif + m_counts = new ( temp ) Loki::Private::LockableTwoRefCountInfo( strong ); + } + else + { + Increment( strong ); + } + } + /** The destructor does not need to do anything since the call to ZapPointer inside StrongPtr::~StrongPtr will do the cleanup which this dtor would have done. @@ -789,6 +809,8 @@ TwoRefLinks( const TwoRefLinks & rhs, bool strong ); + TwoRefLinks( const TwoRefLinks & rhs, bool isNull, bool strong ); + bool Release( bool strong ); void Swap( TwoRefLinks & rhs ); @@ -893,6 +915,49 @@ typedef typename Select<false, const StoredType&, NeverMatched>::Result ExplicitArg; #endif + /// StrongPtr uses this helper class to specify the dynamic-caster constructor. + class DynamicCastHelper {}; + + /// Private constructor is only used for dynamic-casting. + template + < + typename T1, + bool S1, + class OP1, + class CP1, + template < class > class KP1, + template < class > class RP1, + template < class > class DP1, + template < class > class CNP1 + > + StrongPtr( const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs, + bool isNull, const DynamicCastHelper & helper ) + // Dynamic casting from T1 to T and saving result in ownership policy. + : OP( rhs, isNull, Strong ) + { + (void)helper; // do void cast to remove compiler warning. + } + + /// Private constructor is only used for dynamic-casting. + template + < + typename T1, + bool S1, + class OP1, + class CP1, + template < class > class KP1, + template < class > class RP1, + template < class > class DP1, + template < class > class CNP1 + > + StrongPtr( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs, + bool isNull, const DynamicCastHelper & helper ) + // Dynamic casting from T1 to T and saving result in ownership policy. + : OP( rhs, isNull, Strong ) + { + (void)helper; // do void cast to remove compiler warning. + } + public: StrongPtr( void ) : OP( Strong ) @@ -1032,6 +1097,56 @@ } } + /// Dynamically-casts parameter pointer to the type specified by this SmartPtr type. + template + < + typename T1, + bool S1, + class OP1, + class CP1, + template < class > class KP1, + template < class > class RP1, + template < class > class DP1, + template < class > class CNP1 + > + StrongPtr & DynamicCastFrom( const StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) + { + typedef typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::PointerType RightPointerType; + const StrongPtr & sp = reinterpret_cast< const StrongPtr & >( rhs ); + PointerType p = sp.GetPointer(); + const RightPointerType rp = reinterpret_cast< const RightPointerType >( p ); + p = dynamic_cast< const PointerType >( rp ); + const bool isNull = ( NULL == p ); + StrongPtr temp( rhs, isNull, DynamicCastHelper() ); + Swap( temp ); + return *this; + } + + /// Dynamically-casts parameter pointer to the type specified by this SmartPtr type. + template + < + typename T1, + bool S1, + class OP1, + class CP1, + template < class > class KP1, + template < class > class RP1, + template < class > class DP1, + template < class > class CNP1 + > + StrongPtr & DynamicCastFrom( StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 > & rhs ) + { + typedef typename StrongPtr< T1, S1, OP1, CP1, KP1, RP1, DP1, CNP1 >::PointerType RightPointerType; + StrongPtr & sp = reinterpret_cast< StrongPtr & >( rhs ); + PointerType p = sp.GetPointer(); + RightPointerType rp = reinterpret_cast< RightPointerType >( p ); + p = dynamic_cast< PointerType >( rp ); + const bool isNull = ( NULL == p ); + StrongPtr temp( rhs, isNull, DynamicCastHelper() ); + Swap( temp ); + return *this; + } + #ifdef LOKI_ENABLE_FRIEND_TEMPLATE_TEMPLATE_PARAMETER_WORKAROUND // old non standard in class definition of friends @@ -1663,35 +1778,4 @@ namespace std { //////////////////////////////////////////////////////////////////////////////// - /// specialization of std::less for StrongPtr - /// \ingroup SmartPointerGroup - //////////////////////////////////////////////////////////////////////////////// - template - < - typename T, - bool S, - class OP, - class CP, - template < class > class KP, - template < class > class RP, - template < class > class DP, - template < class > class CNP - > - struct less< Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > > - : public binary_function< - Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >, - Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP >, bool > - { - bool operator () ( - const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & lhs, - const Loki::StrongPtr< T, S, OP, CP, KP, RP, DP, CNP > & rhs ) const - { - return ( lhs < rhs ); - } - }; -} - -//////////////////////////////////////////////////////////////////////////////// - -#endif // end file guardian - + /// specialization of std::less for StroeTracker@Private@Loki@@@std@@@std@@QBEXABV123@@Z |
From: <ric...@us...> - 2009-11-02 22:45:57
|
Revision: 1051 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1051&view=rev Author: rich_sposato Date: 2009-11-02 22:45:51 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Added thread-local declaration. Replace sleep with usleep. Modified Paths: -------------- trunk/test/LevelMutex/ThreadPool.cpp Modified: trunk/test/LevelMutex/ThreadPool.cpp =================================================================== --- trunk/test/LevelMutex/ThreadPool.cpp 2009-11-02 22:40:13 UTC (rev 1050) +++ trunk/test/LevelMutex/ThreadPool.cpp 2009-11-02 22:45:51 UTC (rev 1051) @@ -21,6 +21,9 @@ #include <assert.h> #include <process.h> +#if !defined( _MSC_VER ) + #include <unistd.h> // needed for the usleep function. +#endif using namespace ::std; @@ -36,7 +39,7 @@ #endif -volatile Thread * Thread::s_thread = nullptr; +volatile LOKI_THREAD_LOCAL Thread * Thread::s_thread = nullptr; // ---------------------------------------------------------------------------- @@ -94,7 +97,7 @@ #if defined( _MSC_VER ) ::SleepEx( 1, true ); #else - ::sleep( 1 ); + ::usleep( 1000 ); #endif } return true; @@ -343,7 +346,7 @@ #if defined( _MSC_VER ) ::SleepEx( 1, true ); #else - ::sleep( 1 ); + ::usleep( 1000 ); #endif if ( thread->m_status == Thread::Starting ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-02 22:40:21
|
Revision: 1050 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1050&view=rev Author: rich_sposato Date: 2009-11-02 22:40:13 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Moved thread_local declaration to separate header file. Modified Paths: -------------- trunk/test/LevelMutex/ThreadPool.hpp Modified: trunk/test/LevelMutex/ThreadPool.hpp =================================================================== --- trunk/test/LevelMutex/ThreadPool.hpp 2009-11-02 22:38:37 UTC (rev 1049) +++ trunk/test/LevelMutex/ThreadPool.hpp 2009-11-02 22:40:13 UTC (rev 1050) @@ -4,9 +4,9 @@ // Copyright (c) 2008 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -19,6 +19,9 @@ #include <vector> +#include <loki/ThreadLocal.h> + + // ---------------------------------------------------------------------------- typedef void * ( * CallFunction )( void * ); @@ -47,34 +50,6 @@ #endif -/** @par thread_local Keyword - The mutexes require compilers to provide thread local storage - meaning each - thread gets its own copy of the data. The next version of C++ will have a - new keyword, thread_local for that purpose. Some existing compilers already - provide thread local storage using different syntax, so these lines use - thread_local to mimic that syntax. If your compiler provides thread local - storage but using different syntax besides "thread_local", you may want to - modify these lines. If your compiler does not support thread local storage, - you can't use LevelMutex. - */ -#ifndef LOKI_THREAD_LOCAL - #if defined( _MSC_VER ) - #if ( _MSC_VER >= 1300 ) - #define LOKI_THREAD_LOCAL __declspec( thread ) - #else - #error "Only Visual Studio versions 7.0 and after supported." - #endif - - #elif ( __GNUC__ ) - #define LOKI_THREAD_LOCAL __thread - - #else - #warning "Check if your compiler provides thread local storage." - #define LOKI_THREAD_LOCAL thread_local - #endif -#endif - - class ThreadPool; class Thread This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-02 22:38:51
|
Revision: 1049 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1049&view=rev Author: rich_sposato Date: 2009-11-02 22:38:37 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Changed parameter type for main. Modified Paths: -------------- trunk/test/LevelMutex/main.cpp Modified: trunk/test/LevelMutex/main.cpp =================================================================== --- trunk/test/LevelMutex/main.cpp 2009-11-02 05:48:02 UTC (rev 1048) +++ trunk/test/LevelMutex/main.cpp 2009-11-02 22:38:37 UTC (rev 1049) @@ -4,9 +4,9 @@ // Copyright (c) 2008 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -640,7 +640,7 @@ // ---------------------------------------------------------------------------- -int main( unsigned int argc, const char * const argv[] ) +int main( int argc, const char * const argv[] ) { cout << "Starting LevelMutex tests." << endl; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-02 05:48:10
|
Revision: 1048 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1048&view=rev Author: rich_sposato Date: 2009-11-02 05:48:02 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Moved thread_local macro code to separate header file. Added more error values to enum family. Modified Paths: -------------- trunk/include/loki/LevelMutex.h trunk/src/LevelMutex.cpp Modified: trunk/include/loki/LevelMutex.h =================================================================== --- trunk/include/loki/LevelMutex.h 2009-11-02 05:43:58 UTC (rev 1047) +++ trunk/include/loki/LevelMutex.h 2009-11-02 05:48:02 UTC (rev 1048) @@ -1,12 +1,12 @@ //////////////////////////////////////////////////////////////////////////////// // // LevelMutex facility for the Loki Library -// Copyright (c) 2008 Richard Sposato +// Copyright (c) 2008, 2009 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -35,36 +35,15 @@ #endif #if !defined(_WIN32) && !defined(_WIN64) - #include <unistd.h> // declares sleep under Linux + #include <unistd.h> // declares usleep under Linux #endif -/** @par thread_local Keyword - The mutexes require compilers to provide thread local storage - meaning each - thread gets its own copy of the data. The next version of C++ will have a - new keyword, thread_local for that purpose. Some existing compilers already - provide thread local storage using different syntax, so these lines use - thread_local to mimic that syntax. If your compiler provides thread local - storage but using different syntax besides "thread_local", you may want to - modify these lines. If your compiler does not support thread local storage, - you can't use LevelMutex. - */ -#ifndef LOKI_THREAD_LOCAL - #if defined( _MSC_VER ) - #if ( _MSC_VER >= 1300 ) - #define LOKI_THREAD_LOCAL __declspec( thread ) - #else - #error "Only Visual Studio versions 7.0 and after supported." - #endif +#include <loki/ThreadLocal.h> // Include Loki's form of thread_local declaration. - #elif ( __GNUC__ ) - #define LOKI_THREAD_LOCAL __thread +#if !defined( LOKI_THREAD_LOCAL ) + #warning "Your compiler will not allow Loki::LevelMutex." +#else - #else - #warning "Check if your compiler provides thread local storage." - #define LOKI_THREAD_LOCAL thread_local - #endif -#endif - #if defined( DEBUG ) || defined( _DEBUG ) #define LOKI_MUTEX_DEBUG_CODE( x ) x #else @@ -106,7 +85,11 @@ InvalidAttribute, ///< PThread mutex improperly initialized. InvalidAddress, ///< Bad pointer used to initialize a PThread mutex. ExceptionThrown, ///< Exception caught in mutex operation. + InvertedPriority, ///< Mutex already locked by thread with lower priority. MayDeadlock, ///< Locking this mutex may cause a deadlock. + NotPrivileged, ///< Program does not have privilege to initialize mutexes. + NotEnoughMemory, ///< Program does not have enough memory to initialize mutex. + NotEnoughResources, ///< Program does not have enough resources to initialize mutex. OtherError ///< Unknown error occurred. }; }; @@ -374,7 +357,7 @@ */ virtual MutexErrors::Type LockThis( unsigned int milliSeconds ) volatile = 0; - /// Called only by MultiUnlock to unlock each particular mutex within a container. + /// Called only by MultiUnlock to unlock each particular mutex within a container. virtual MutexErrors::Type UnlockThis( void ) volatile = 0; /// Pointer to singly-linked list of mutexes locked by the current thread. @@ -565,7 +548,7 @@ Implements a sleeping loop to wait for the mutex to unlock. @par Purpose - Since this class puts the thread to sleep for short intervals, you can use this + Since this class puts the thread to sleep for short intervals, you can use this class for most of your mutexes. Especially for locking any high level resources where any one operation on the resouce consumes many CPU cycles. The purpose of this mutex is to reduce the number of CPU cycles spent in idle loops. All @@ -1101,7 +1084,7 @@ /// Returns true if the mutex is locked by this object. inline bool IsLocked( void ) const { return m_locked; } - /// Provides access to mutex controlled by this. + /// Provides access to mutex controlled by this. const volatile LevelMutexInfo & GetMutex( void ) const { return m_mutex; } private: @@ -1179,7 +1162,7 @@ /// Returns true if the mutexes are locked by this object. inline bool IsLocked( void ) const { return m_locked; } - /// Provides access to the collection of mutexes controlled by this. + /// Provides access to the collection of mutexes controlled by this. const LevelMutexInfo::MutexContainer & GetMutexes( void ) const { return m_mutexes; } private: @@ -1202,4 +1185,6 @@ } // end namespace Loki +#endif // end else if compiler allows thread_local storage + #endif // end file guardian Modified: trunk/src/LevelMutex.cpp =================================================================== --- trunk/src/LevelMutex.cpp 2009-11-02 05:43:58 UTC (rev 1047) +++ trunk/src/LevelMutex.cpp 2009-11-02 05:48:02 UTC (rev 1048) @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // // LevelMutex facility for the Loki Library -// Copyright (c) 2008 Richard Sposato +// Copyright (c) 2008, 2009 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // // Permission to use, copy, modify, distribute and sell this software for any @@ -18,37 +18,23 @@ /// @file LevelMutex.cpp Contains functions needed by LevelMutex class. + // ---------------------------------------------------------------------------- -// First assume the compiler does allow thread-local storage by #defining the -// macro which allows compiler to see the code inside this file. -// Then #undefine the macro for compilers which are known for not supporting -// thread-local storage. -#define COMPILER_ALLOWS_THREAD_LOCAL_STORAGE 1 +#include "../include/loki/LevelMutex.h" -// The __APPLE__ macro does not refer to a compiler, but to the Apple OSX operating system. -#if defined( __APPLE__ ) - #warning "GCC for Apple does not allow thread_local storage, so you can not use Loki::LevelMutex." - #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE -#endif +#if defined( LOKI_THREAD_LOCAL ) -#if ( defined( __CYGWIN__ ) && ( __GNUC__ <= 3 ) ) - #warning "Older versions of GCC for Cygwin do not allow thread_local storage, so you can not use Loki::LevelMutex." - #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE -#endif - -#if defined( COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) - - -#include "../include/loki/LevelMutex.h" - #if !defined( _MSC_VER ) #include <unistd.h> // needed for usleep function. #endif #include <algorithm> #include <cerrno> +#if defined( DEBUG ) || defined( _DEBUG ) + #define DEBUG_LOKI_LEVEL_MUTEX 1 + #include <iostream> +#endif - using namespace ::std; // define nullptr even though new compilers will have this keyword just so we @@ -806,6 +792,9 @@ switch ( result ) { case 0: +//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) +// cout << __FUNCTION__ << '\t' << __LINE__ << endl; +//#endif return; case EBUSY: throw MutexException( "pthread mutex already initialized!", @@ -817,6 +806,18 @@ case EFAULT: throw MutexException( "pthread mutex has an invalid address!", level, MutexErrors::InvalidAddress ); + case ENOMEM: + throw MutexException( + "System does not have enough memory to initialize a pthread mutex.", + level, MutexErrors::NotEnoughMemory ); + case EPERM: + throw MutexException( + "Program does not have privilege to initialize a pthread mutex.", + level, MutexErrors::NotPrivileged ); + case EAGAIN: + throw MutexException( + "Program does not have resources to initialize another pthread mutex.", + level, MutexErrors::NotEnoughResources ); } #endif } @@ -830,6 +831,9 @@ #if defined( _MSC_VER ) ::DeleteCriticalSection( &m_mutex ); #else +//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) +// cout << __FUNCTION__ << '\t' << __LINE__ << endl; +//#endif ::pthread_mutex_destroy( &m_mutex ); #endif } @@ -853,17 +857,29 @@ switch ( result ) { case 0: +//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) +// cout << __FUNCTION__ << '\t' << __LINE__ << endl; +//#endif break; default: case EINVAL: - throw MutexException( "pthread mutex not initialized properly!", - GetLevel(), MutexErrors::NotInitialized ); + throw MutexException( "pthread mutex locked by thread with lower priority!", + GetLevel(), MutexErrors::InvertedPriority ); case EFAULT : throw MutexException( "pthread mutex is not valid!", GetLevel(), MutexErrors::InvalidAddress ); case EDEADLK: throw MutexException( "locking this pthread mutex may cause a deadlock!", GetLevel(), MutexErrors::MayDeadlock ); + case EBUSY: + throw MutexException( "Mutex is already locked by this thread.", + GetLevel(), MutexErrors::AlreadyLocked ); + case EAGAIN: + throw MutexException( "Mutex already locked too many times by this thread.", + GetLevel(), MutexErrors::TooMuchRecursion ); + case EPERM: + throw MutexException( "This thread does not own the mutex.", + GetLevel(), MutexErrors::NotPrivileged ); } #endif return MutexErrors::Success; @@ -884,6 +900,9 @@ switch ( result ) { case 0: +//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) +// cout << __FUNCTION__ << '\t' << __LINE__ << endl; +//#endif return MutexErrors::Success; default: case EBUSY: @@ -891,6 +910,9 @@ case EAGAIN: throw MutexException( "pthread mutex reached recursion limit!", GetLevel(), MutexErrors::TooMuchRecursion ); + case EINVAL: + throw MutexException( "pthread mutex locked by thread with lower priority!", + GetLevel(), MutexErrors::InvertedPriority ); } return MutexErrors::TryFailed; #endif @@ -910,6 +932,9 @@ if ( EPERM == result ) throw MutexException( "current thread did not lock this pthread mutex!", GetLevel(), MutexErrors::NotLockedByThread ); +//#if defined( DEBUG_LOKI_LEVEL_MUTEX ) +// cout << __FUNCTION__ << '\t' << __LINE__ << endl; +//#endif #endif return MutexErrors::Success; } @@ -1165,4 +1190,4 @@ } // end namespace Loki -#endif // #if defined( COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) +#endif // #if defined( LOKI_THREAD_LOCAL ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-02 05:44:05
|
Revision: 1047 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1047&view=rev Author: rich_sposato Date: 2009-11-02 05:43:58 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Added ThreadLocal.h header file. Modified Paths: -------------- trunk/src/Library_MSVC9.vcproj Modified: trunk/src/Library_MSVC9.vcproj =================================================================== --- trunk/src/Library_MSVC9.vcproj 2009-11-02 05:37:41 UTC (rev 1046) +++ trunk/src/Library_MSVC9.vcproj 2009-11-02 05:43:58 UTC (rev 1047) @@ -329,6 +329,10 @@ > </File> <File + RelativePath="..\include\loki\ThreadLocal.h" + > + </File> + <File RelativePath="..\include\loki\Threads.h" > </File> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-02 05:37:49
|
Revision: 1046 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1046&view=rev Author: rich_sposato Date: 2009-11-02 05:37:41 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Added ThreadLocal.h header file. Modified Paths: -------------- trunk/Loki.cbp Modified: trunk/Loki.cbp =================================================================== --- trunk/Loki.cbp 2009-11-02 05:34:21 UTC (rev 1045) +++ trunk/Loki.cbp 2009-11-02 05:37:41 UTC (rev 1046) @@ -95,6 +95,7 @@ <Unit filename="include\loki\SmallObj.h" /> <Unit filename="include\loki\SmartPtr.h" /> <Unit filename="include\loki\StrongPtr.h" /> + <Unit filename="include\loki\ThreadLocal.h" /> <Unit filename="include\loki\Threads.h" /> <Unit filename="include\loki\Tuple.h" /> <Unit filename="include\loki\TypeManip.h" /> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-11-02 05:34:28
|
Revision: 1045 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1045&view=rev Author: rich_sposato Date: 2009-11-02 05:34:21 +0000 (Mon, 02 Nov 2009) Log Message: ----------- Added new header to Loki. Added Paths: ----------- trunk/include/loki/ThreadLocal.h Added: trunk/include/loki/ThreadLocal.h =================================================================== --- trunk/include/loki/ThreadLocal.h (rev 0) +++ trunk/include/loki/ThreadLocal.h 2009-11-02 05:34:21 UTC (rev 1045) @@ -0,0 +1,69 @@ +//////////////////////////////////////////////////////////////////////////////// +// The Loki Library +// Copyright (c) 2009 by Rich Sposato +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this +// permission notice appear in supporting documentation. +// The author makes no representations about the +// suitability of this software for any purpose. It is provided "as is" +// without express or implied warranty. +//////////////////////////////////////////////////////////////////////////////// + +#ifndef LOKI_THREAD_LOCAL_H_INCLUDED +#define LOKI_THREAD_LOCAL_H_INCLUDED + +// $Id$ + + +// ---------------------------------------------------------------------------- + +// First assume the compiler does allow thread-local storage by #defining the +// macro which allows compiler to see the code inside this file. +// Then #undefine the macro for compilers which are known for not supporting +// thread-local storage. +#define LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE 1 + +// The __APPLE__ macro does not refer to a compiler, but to the Apple OSX operating system. +#if defined( __APPLE__ ) + #warning "GCC for Apple does not allow thread_local storage, so you can not use some parts of Loki." + #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE +#endif + +#if ( defined( __CYGWIN__ ) && ( __GNUC__ <= 3 ) ) + #warning "Older versions of GCC for Cygwin do not allow thread_local storage, so you can not use some parts of Loki." + #undef COMPILER_ALLOWS_THREAD_LOCAL_STORAGE +#endif + +#if defined( LOKI_THINKS_COMPILER_ALLOWS_THREAD_LOCAL_STORAGE ) && !defined( LOKI_THREAD_LOCAL ) + +/** @par thread_local Keyword + Some parts of Loki require compilers to provide thread local storage - meaning + each thread gets its own copy of the data. The next version of C++ will have + a new keyword, thread_local for that purpose. Some existing compilers already + provide thread local storage using different syntax, so these lines use + thread_local to mimic that syntax. If your compiler provides thread local + storage but using different syntax besides "thread_local", you may want to + modify these lines. If your compiler does not support thread local storage, + you can't use some parts of Loki. + */ + #if defined( _MSC_VER ) + #if ( _MSC_VER >= 1300 ) + #define LOKI_THREAD_LOCAL __declspec( thread ) + #else + #error "Only Visual Studio versions 7.0 and after supported." + #endif + + #elif ( __GNUC__ ) + #define LOKI_THREAD_LOCAL __thread + + #else + #warning "Check if your compiler provides thread local storage." + #define LOKI_THREAD_LOCAL thread_local + #endif + +#endif // if compiler allows thread_local storage and LOKI_THREAD_LOCAL macro not defined yet + +// ---------------------------------------------------------------------------- + +#endif // end file guardian This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-10-16 06:00:47
|
Revision: 1044 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1044&view=rev Author: rich_sposato Date: 2009-10-16 06:00:40 +0000 (Fri, 16 Oct 2009) Log Message: ----------- Renamed Unlocker to remove compiler warning. Changed function calls for sleeping. Modified Paths: -------------- trunk/test/LevelMutex/Thing.cpp Modified: trunk/test/LevelMutex/Thing.cpp =================================================================== --- trunk/test/LevelMutex/Thing.cpp 2009-10-16 05:54:12 UTC (rev 1043) +++ trunk/test/LevelMutex/Thing.cpp 2009-10-16 06:00:40 UTC (rev 1044) @@ -1,12 +1,12 @@ //////////////////////////////////////////////////////////////////////////////// // // Part of LevelMutex test program for The Loki Library -// Copyright (c) 2008 Richard Sposato +// Copyright (c) 2008, 2009 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -22,6 +22,9 @@ #include "Thing.hpp" #include <assert.h> +#if !defined( _MSC_VER ) + #include <unistd.h> +#endif #include <algorithm> #include <functional> @@ -68,11 +71,9 @@ { assert( NULL != this ); #if defined( _MSC_VER ) - SetSleepTime( 5 ); SetWakable( false ); -#else - SetSleepTime( 1 ); #endif + SetSleepTime( 5 ); } // ---------------------------------------------------------------------------- @@ -262,10 +263,10 @@ #if defined( _MSC_VER ) ::SleepEx( milliSeconds, true ); #elif ( __GNUC__ ) - unsigned int seconds = milliSeconds / 1000; - if ( 0 == seconds ) - seconds = 1; - ::_sleep( seconds ); + unsigned int microseconds = milliSeconds * 1000; + if ( 0 == microseconds ) + microseconds = 1; + ::usleep( microseconds ); #else #error "Find out if your compiler supports a sleep command and add it here." #endif @@ -346,11 +347,9 @@ { assert( NULL != this ); #if defined( _MSC_VER ) - m_mutex.GetMutexPolicy().SetSleepTime( 5 ); m_mutex.GetMutexPolicy().SetWakable( false ); -#else - m_mutex.GetMutexPolicy().SetSleepTime( 1 ); #endif + m_mutex.GetMutexPolicy().SetSleepTime( 5 ); } // ---------------------------------------------------------------------------- @@ -365,8 +364,11 @@ void Thing::Print( unsigned int value, unsigned int index, unsigned int startSize ) const volatile { assert( NULL != this ); - volatile SleepMutex & mutex = const_cast< volatile SleepMutex & >( m_mutex ); - ConstSingleThingLocker pSafeThis( *this, mutex ); + MutexLocker locker( m_mutex ); + assert( m_mutex.IsLockedByCurrentThread() ); +// volatile SleepMutex & mutex = const_cast< volatile SleepMutex & >( m_mutex ); +// ConstSingleThingLocker pSafeThis( *this, mutex ); + const Thing * pSafeThis = const_cast< const Thing * >( this ); pSafeThis->Print( value, index, startSize ); } @@ -453,11 +455,9 @@ { assert( NULL != this ); #if defined( _MSC_VER ) - m_mutex.GetMutexPolicy().SetSleepTime( 5 ); m_mutex.GetMutexPolicy().SetWakable( false ); -#else - m_mutex.GetMutexPolicy().SetSleepTime( 1 ); #endif + m_mutex.GetMutexPolicy().SetSleepTime( 5 ); } // ---------------------------------------------------------------------------- @@ -469,7 +469,7 @@ // ---------------------------------------------------------------------------- -LevelThing::Unlocker LevelThing::LockHierarchy( void ) volatile +LevelThing::MyUnlocker LevelThing::LockHierarchy( void ) volatile { assert( NULL != this ); for ( signed ii = m_place; 0 <= ii; --ii ) @@ -481,7 +481,7 @@ break; } - Unlocker unlocker( this ); + MyUnlocker unlocker( this ); return unlocker; } @@ -578,11 +578,9 @@ { assert( NULL != this ); #if defined( _MSC_VER ) - m_mutex.GetMutexPolicy().SetSleepTime( 5 ); m_mutex.GetMutexPolicy().SetWakable( false ); -#else - m_mutex.GetMutexPolicy().SetSleepTime( 1 ); #endif + m_mutex.GetMutexPolicy().SetSleepTime( 5 ); } // ---------------------------------------------------------------------------- This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-10-16 05:54:20
|
Revision: 1043 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1043&view=rev Author: rich_sposato Date: 2009-10-16 05:54:12 +0000 (Fri, 16 Oct 2009) Log Message: ----------- Renamed Unlocker to remove compiler warning. Modified Paths: -------------- trunk/test/LevelMutex/MultiThreadTests.cpp trunk/test/LevelMutex/Thing.hpp Modified: trunk/test/LevelMutex/MultiThreadTests.cpp =================================================================== --- trunk/test/LevelMutex/MultiThreadTests.cpp 2009-10-11 05:35:15 UTC (rev 1042) +++ trunk/test/LevelMutex/MultiThreadTests.cpp 2009-10-16 05:54:12 UTC (rev 1043) @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////////////////////////// // // Part of LevelMutex test program for The Loki Library -// Copyright (c) 2008 Richard Sposato +// Copyright (c) 2008, 2009 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // // Permission to use, copy, modify, distribute and sell this software for any @@ -855,7 +855,7 @@ { thing = LevelThing::GetFromPool( ii ); assert( nullptr != thing ); - LevelThing::Unlocker unlocker( thing->LockHierarchy() ); + LevelThing::MyUnlocker unlocker( thing->LockHierarchy() ); (void)unlocker; thing->SetValue( value ); ::GoToSleep( 3 ); @@ -867,7 +867,7 @@ const unsigned int randomIndex = ( ::rand() % thingCount ); thing = LevelThing::GetFromPool( randomIndex ); assert( nullptr != thing ); - LevelThing::Unlocker unlocker( thing->LockHierarchy() ); + LevelThing::MyUnlocker unlocker( thing->LockHierarchy() ); (void)unlocker; thing->SetValue( value ); ::GoToSleep( 3 ); Modified: trunk/test/LevelMutex/Thing.hpp =================================================================== --- trunk/test/LevelMutex/Thing.hpp 2009-10-11 05:35:15 UTC (rev 1042) +++ trunk/test/LevelMutex/Thing.hpp 2009-10-16 05:54:12 UTC (rev 1043) @@ -1,12 +1,12 @@ //////////////////////////////////////////////////////////////////////////////// // // Part of LevelMutex test program for The Loki Library -// Copyright (c) 2008 Richard Sposato +// Copyright (c) 2008, 2009 Richard Sposato // The copyright on this file is protected under the terms of the MIT license. // -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this +// Permission to use, copy, modify, distribute and sell this software for any +// purpose is hereby granted without fee, provided that the above copyright +// notice appear in all copies and that both that copyright notice and this // permission notice appear in supporting documentation. // // The author makes no representations about the suitability of this software @@ -207,7 +207,7 @@ { public: - typedef Unlocker< LevelThing > Unlocker; + typedef Unlocker< LevelThing > MyUnlocker; static volatile LevelThing * GetFromPool( unsigned int index ); @@ -215,7 +215,7 @@ static void DestroyPool( void ); - Unlocker LockHierarchy( void ) volatile; + MyUnlocker LockHierarchy( void ) volatile; void UnlockHierarchy( void ) volatile; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ric...@us...> - 2009-10-11 05:35:23
|
Revision: 1042 http://loki-lib.svn.sourceforge.net/loki-lib/?rev=1042&view=rev Author: rich_sposato Date: 2009-10-11 05:35:15 +0000 (Sun, 11 Oct 2009) Log Message: ----------- Changed some project settings. Modified Paths: -------------- trunk/test/Checker/Checker_MSVC_9.vcproj Modified: trunk/test/Checker/Checker_MSVC_9.vcproj =================================================================== --- trunk/test/Checker/Checker_MSVC_9.vcproj 2009-10-11 05:31:02 UTC (rev 1041) +++ trunk/test/Checker/Checker_MSVC_9.vcproj 2009-10-11 05:35:15 UTC (rev 1042) @@ -40,6 +40,7 @@ <Tool Name="VCCLCompilerTool" Optimization="0" + AdditionalIncludeDirectories="..\..\include" StringPooling="true" MinimalRebuild="true" BasicRuntimeChecks="3" @@ -112,10 +113,12 @@ Name="VCCLCompilerTool" Optimization="2" EnableIntrinsicFunctions="true" + AdditionalIncludeDirectories="..\..\include" + StringPooling="true" RuntimeLibrary="2" EnableFunctionLevelLinking="true" - WarningLevel="3" - DebugInformationFormat="3" + WarningLevel="4" + DebugInformationFormat="0" /> <Tool Name="VCManagedResourceCompilerTool" This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |