diff --git a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
index c1e9e41faf..3e48cd0758 100644
--- a/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
+++ b/examples/DemoRunner/Builds/Android/app/CMakeLists.txt
@@ -1067,6 +1067,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
@@ -3155,6 +3156,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
index 5e6738d512..9c47a7d0ab 100644
--- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj
@@ -1358,6 +1358,9 @@
true
+
+ true
+
true
diff --git a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
index 0655f18e3f..013db46f94 100644
--- a/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2017/DemoRunner_App.vcxproj.filters
@@ -1975,6 +1975,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
index 473fee06cb..c3bf0a5f6b 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj
@@ -1358,6 +1358,9 @@
true
+
+ true
+
true
diff --git a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
index 3d9128a0ca..f21359880d 100644
--- a/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2019/DemoRunner_App.vcxproj.filters
@@ -1975,6 +1975,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
index aa280cf5e5..a38de57541 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj
@@ -1358,6 +1358,9 @@
true
+
+ true
+
true
diff --git a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
index f53488c313..07f72e220a 100644
--- a/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
+++ b/examples/DemoRunner/Builds/VisualStudio2022/DemoRunner_App.vcxproj.filters
@@ -1975,6 +1975,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
index e518538fe3..75a5a5ebd8 100644
--- a/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPerformanceTest/Builds/Android/app/CMakeLists.txt
@@ -943,6 +943,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
@@ -2731,6 +2732,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
index 737fc40694..8aea52796d 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj
@@ -1198,6 +1198,9 @@
true
+
+ true
+
true
diff --git a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
index 0c3a2558e4..c910b58613 100644
--- a/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
+++ b/extras/AudioPerformanceTest/Builds/VisualStudio2022/AudioPerformanceTest_App.vcxproj.filters
@@ -1684,6 +1684,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
index 3dbc41c38e..62355b3a17 100644
--- a/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
+++ b/extras/AudioPluginHost/Builds/Android/app/CMakeLists.txt
@@ -976,6 +976,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
@@ -2917,6 +2918,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
index c7b91ddd18..f7f86f753b 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj
@@ -1206,6 +1206,9 @@
true
+
+ true
+
true
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
index 8091bf3da5..4f3e0d2121 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2017/AudioPluginHost_App.vcxproj.filters
@@ -1759,6 +1759,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
index cda56c5558..20fc8aa31a 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj
@@ -1206,6 +1206,9 @@
true
+
+ true
+
true
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
index d9c7b672fb..262a681ced 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2019/AudioPluginHost_App.vcxproj.filters
@@ -1759,6 +1759,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
index 926b3dce21..eaa1ac625b 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj
@@ -1206,6 +1206,9 @@
true
+
+ true
+
true
diff --git a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
index 1723756d68..0c45c373cd 100644
--- a/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
+++ b/extras/AudioPluginHost/Builds/VisualStudio2022/AudioPluginHost_App.vcxproj.filters
@@ -1759,6 +1759,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
index 3a13f26699..b56adc8f62 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
+++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj
@@ -250,6 +250,9 @@
true
+
+ true
+
true
diff --git a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
index 66ba5850dd..112fb4f767 100644
--- a/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
+++ b/extras/BinaryBuilder/Builds/VisualStudio2022/BinaryBuilder_ConsoleApp.vcxproj.filters
@@ -190,6 +190,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
index 9e29bd0666..872b7642f7 100644
--- a/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
+++ b/extras/NetworkGraphicsDemo/Builds/Android/app/CMakeLists.txt
@@ -947,6 +947,7 @@ add_library( ${BINARY_NAME}
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
@@ -2815,6 +2816,7 @@ set_source_files_properties(
"../../../../../modules/juce_core/memory/juce_Reservoir.h"
"../../../../../modules/juce_core/memory/juce_ScopedPointer.h"
"../../../../../modules/juce_core/memory/juce_SharedResourcePointer.h"
+ "../../../../../modules/juce_core/memory/juce_SharedResourcePointer_test.cpp"
"../../../../../modules/juce_core/memory/juce_Singleton.h"
"../../../../../modules/juce_core/memory/juce_WeakReference.h"
"../../../../../modules/juce_core/misc/juce_ConsoleApplication.cpp"
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
index 6e24d309d6..861ca3767f 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj
@@ -1198,6 +1198,9 @@
true
+
+ true
+
true
diff --git a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
index 264574b087..d06eeb19d7 100644
--- a/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
+++ b/extras/NetworkGraphicsDemo/Builds/VisualStudio2022/NetworkGraphicsDemo_App.vcxproj.filters
@@ -1714,6 +1714,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
index 43e5cacae9..110c58d130 100644
--- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj
@@ -389,6 +389,9 @@
true
+
+ true
+
true
diff --git a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
index 6eaee41401..094129236d 100644
--- a/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2017/Projucer_App.vcxproj.filters
@@ -670,6 +670,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
index 9f5563944b..1ca13898d5 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj
@@ -389,6 +389,9 @@
true
+
+ true
+
true
diff --git a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
index 3c3c1ba730..edd2f6b27f 100644
--- a/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2019/Projucer_App.vcxproj.filters
@@ -670,6 +670,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
index 0d9a8a6f2a..5e5becbd99 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj
@@ -389,6 +389,9 @@
true
+
+ true
+
true
diff --git a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
index 8491cc628c..4a766b6adc 100644
--- a/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
+++ b/extras/Projucer/Builds/VisualStudio2022/Projucer_App.vcxproj.filters
@@ -670,6 +670,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
index 8dffa7fe96..a2fd8fa438 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj
@@ -1214,6 +1214,9 @@
true
+
+ true
+
true
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
index 014fc8dff3..b78f0f05d9 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2017/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -1780,6 +1780,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
index 8d72c81591..cce48e72c5 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj
@@ -1214,6 +1214,9 @@
true
+
+ true
+
true
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
index 445ec06d83..7441dffe7b 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2019/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -1780,6 +1780,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
index 77eadcf51b..2e6d7d4d8d 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj
@@ -1214,6 +1214,9 @@
true
+
+ true
+
true
diff --git a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
index 47d6716404..71a26040dc 100644
--- a/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
+++ b/extras/UnitTestRunner/Builds/VisualStudio2022/UnitTestRunner_ConsoleApp.vcxproj.filters
@@ -1780,6 +1780,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
index f3d64e66a6..f0ad51afa5 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj
@@ -1197,6 +1197,9 @@
true
+
+ true
+
true
diff --git a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
index 7a832cf211..aa2d783a33 100644
--- a/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
+++ b/extras/WindowsDLL/Builds/VisualStudio2022/WindowsDLL_StaticLibrary.vcxproj.filters
@@ -1711,6 +1711,9 @@
JUCE Modules\juce_core\memory
+
+ JUCE Modules\juce_core\memory
+
JUCE Modules\juce_core\misc
diff --git a/modules/juce_core/juce_core.cpp b/modules/juce_core/juce_core.cpp
index 60878dc9c7..ec5d450261 100644
--- a/modules/juce_core/juce_core.cpp
+++ b/modules/juce_core/juce_core.cpp
@@ -285,6 +285,7 @@
#include "misc/juce_EnumHelpers_test.cpp"
#include "containers/juce_FixedSizeFunction_test.cpp"
#include "javascript/juce_JSONSerialisation_test.cpp"
+ #include "memory/juce_SharedResourcePointer_test.cpp"
#if JUCE_MAC || JUCE_IOS
#include "native/juce_ObjCHelpers_mac_test.mm"
#endif
diff --git a/modules/juce_core/memory/juce_SharedResourcePointer.h b/modules/juce_core/memory/juce_SharedResourcePointer.h
index 98570b9b07..6416898247 100644
--- a/modules/juce_core/memory/juce_SharedResourcePointer.h
+++ b/modules/juce_core/memory/juce_SharedResourcePointer.h
@@ -87,74 +87,94 @@ public:
using. Otherwise, if this is the first SharedResourcePointer to be created,
then a shared object will be created automatically.
*/
- SharedResourcePointer()
- {
- initialise();
- }
+ SharedResourcePointer() = default;
- SharedResourcePointer (const SharedResourcePointer&)
- {
- initialise();
- }
+ /** Copy constructor. */
+ SharedResourcePointer (const SharedResourcePointer&) = default;
+
+ /** Move constructor. */
+ SharedResourcePointer (SharedResourcePointer&&) noexcept = default;
/** Destructor.
If no other SharedResourcePointer objects exist, this will also delete
the shared object to which it refers.
*/
- ~SharedResourcePointer()
- {
- auto& holder = getSharedObjectHolder();
- const SpinLock::ScopedLockType sl (holder.lock);
+ ~SharedResourcePointer() = default;
- if (--(holder.refCount) == 0)
- holder.sharedInstance = nullptr;
- }
+ /** Returns a pointer to the shared object. */
+ operator SharedObjectType*() const noexcept { return sharedObject.get(); }
- /** Returns the shared object. */
- operator SharedObjectType*() const noexcept { return sharedObject; }
-
- /** Returns the shared object. */
+ /** Returns a reference to the shared object. */
SharedObjectType& get() const noexcept { return *sharedObject; }
- /** Returns the object that this pointer references. */
+ /** Returns a reference to the shared object. */
SharedObjectType& getObject() const noexcept { return *sharedObject; }
- /** Returns the shared object pointer. */
- SharedObjectType* operator->() const noexcept { return sharedObject; }
+ /** Returns a pointer to the shared object. */
+ SharedObjectType* operator->() const noexcept { return sharedObject.get(); }
- /** Returns the number of SharedResourcePointers that are currently holding the shared object. */
- int getReferenceCount() const noexcept { return getSharedObjectHolder().refCount; }
+ /** Returns a reference to the shared object. */
+ SharedObjectType& operator*() const noexcept { return *sharedObject; }
+
+ #ifndef DOXYGEN
+ [[deprecated ("If you are relying on this function please inform the JUCE team as we are planing on removing this in a subsequent release")]]
+ int getReferenceCount() const noexcept { return (int) sharedObject.use_count(); }
+ #endif
+
+ /** Returns the SharedResourcePointer if one already exists, or a null optional otherwise. */
+ static std::optional getSharedObjectWithoutCreating()
+ {
+ if (auto sharedPtr = weak().lock())
+ return SharedResourcePointer { std::move (sharedPtr) };
+
+ return {};
+ }
private:
- struct SharedObjectHolder
+ explicit SharedResourcePointer (std::shared_ptr&& other) noexcept
+ : sharedObject (std::move (other))
{
- SpinLock lock;
- std::unique_ptr sharedInstance;
- int refCount;
+ jassert (sharedObject != nullptr);
+ }
+
+ class Weak
+ {
+ public:
+ std::shared_ptr lock()
+ {
+ const SpinLock::ScopedLockType lock { mutex };
+ return ptr.lock();
+ }
+
+ std::shared_ptr lockOrCreate()
+ {
+ const SpinLock::ScopedLockType lock { mutex };
+
+ if (auto locked = ptr.lock())
+ return locked;
+
+ auto shared = std::make_shared();
+ ptr = shared;
+ return shared;
+ }
+
+ private:
+ SpinLock mutex;
+ std::weak_ptr ptr;
};
- static SharedObjectHolder& getSharedObjectHolder() noexcept
+ inline static Weak& weak()
{
- static void* holder [(sizeof (SharedObjectHolder) + sizeof (void*) - 1) / sizeof (void*)] = { nullptr };
- return *reinterpret_cast (holder);
+ static Weak weak;
+ return weak;
}
- SharedObjectType* sharedObject;
-
- void initialise()
- {
- auto& holder = getSharedObjectHolder();
- const SpinLock::ScopedLockType sl (holder.lock);
-
- if (++(holder.refCount) == 1)
- holder.sharedInstance.reset (new SharedObjectType());
-
- sharedObject = holder.sharedInstance.get();
- }
+ std::shared_ptr sharedObject = weak().lockOrCreate();
// There's no need to assign to a SharedResourcePointer because every
// instance of the class is exactly the same!
SharedResourcePointer& operator= (const SharedResourcePointer&) = delete;
+ SharedResourcePointer& operator= (SharedResourcePointer&&) noexcept = delete;
JUCE_LEAK_DETECTOR (SharedResourcePointer)
};
diff --git a/modules/juce_core/memory/juce_SharedResourcePointer_test.cpp b/modules/juce_core/memory/juce_SharedResourcePointer_test.cpp
new file mode 100644
index 0000000000..9cf97c1799
--- /dev/null
+++ b/modules/juce_core/memory/juce_SharedResourcePointer_test.cpp
@@ -0,0 +1,87 @@
+/*
+ ==============================================================================
+
+ This file is part of the JUCE library.
+ Copyright (c) 2022 - Raw Material Software Limited
+
+ JUCE is an open source library subject to commercial or open-source
+ licensing.
+
+ The code included in this file is provided under the terms of the ISC license
+ http://www.isc.org/downloads/software-support-policy/isc-license. Permission
+ To use, copy, modify, and/or distribute this software for any purpose with or
+ without fee is hereby granted provided that the above copyright notice and
+ this permission notice appear in all copies.
+
+ JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
+ EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
+ DISCLAIMED.
+
+ ==============================================================================
+*/
+
+namespace juce
+{
+
+class SharedResourcePointerTest final : public UnitTest
+{
+public:
+ SharedResourcePointerTest()
+ : UnitTest ("SharedResourcePointer", UnitTestCategories::memory) {}
+
+ void runTest() final
+ {
+ beginTest ("Only one instance is created");
+ {
+ static int count = 0;
+ struct CountIncrementer { CountIncrementer() { ++count; } };
+ expect (count == 0);
+
+ const SharedResourcePointer instance1;
+ expect (count == 1);
+
+ const SharedResourcePointer instance2;
+ expect (count == 1);
+
+ expect (&instance1.get() == &instance2.get());
+ }
+
+ beginTest ("The shared object is destroyed when the reference count reaches 0");
+ {
+ static int count = 0;
+ struct ReferenceCounter
+ {
+ ReferenceCounter() { ++count; }
+ ~ReferenceCounter() { --count; }
+ };
+
+ expect (count == 0);
+
+ {
+ const SharedResourcePointer instance1;
+ const SharedResourcePointer instance2;
+ expect (count == 1);
+ }
+
+ expect (count == 0);
+ }
+
+ beginTest ("getInstanceWithoutCreating()");
+ {
+ struct Object{};
+
+ expect (SharedResourcePointer