]> git.sesse.net Git - casparcg/commitdiff
Updated some libraries to newer versions and/or versions compiled for vc12 (freeimage...
authorHelge Norberg <helge.norberg@svt.se>
Wed, 11 Feb 2015 11:55:39 +0000 (12:55 +0100)
committerHelge Norberg <helge.norberg@svt.se>
Wed, 11 Feb 2015 11:55:39 +0000 (12:55 +0100)
269 files changed:
dependencies64/freeimage/bin/FreeImage.dll
dependencies64/freeimage/bin/FreeImaged.dll
dependencies64/freeimage/include/FreeImage.h
dependencies64/freeimage/lib/FreeImage.lib
dependencies64/freeimage/lib/FreeImaged.lib
dependencies64/gtest/lib/gtest.lib
dependencies64/gtest/lib/gtestd.lib
dependencies64/sfml/extlibs/lib/freetype.lib [new file with mode: 0644]
dependencies64/sfml/extlibs/lib/freetype248.lib [deleted file]
dependencies64/sfml/extlibs/lib/freetype248_D.lib [deleted file]
dependencies64/sfml/extlibs/lib/glew.lib [new file with mode: 0644]
dependencies64/sfml/extlibs/lib/jpeg.lib [new file with mode: 0644]
dependencies64/sfml/extlibs/lib/openal32.lib [new file with mode: 0644]
dependencies64/sfml/extlibs/lib/sndfile.lib [new file with mode: 0644]
dependencies64/sfml/include/SFML/Audio.hpp
dependencies64/sfml/include/SFML/Audio/Export.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Audio/Listener.hpp
dependencies64/sfml/include/SFML/Audio/Music.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Audio/Sound.hpp
dependencies64/sfml/include/SFML/Audio/SoundBuffer.hpp
dependencies64/sfml/include/SFML/Audio/SoundBufferRecorder.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Audio/SoundRecorder.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Audio/SoundSource.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Audio/SoundStream.hpp
dependencies64/sfml/include/SFML/Config.hpp
dependencies64/sfml/include/SFML/Graphics.hpp
dependencies64/sfml/include/SFML/Graphics/BlendMode.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/CircleShape.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Color.hpp
dependencies64/sfml/include/SFML/Graphics/ConvexShape.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Drawable.hpp
dependencies64/sfml/include/SFML/Graphics/Export.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Font.hpp
dependencies64/sfml/include/SFML/Graphics/Glyph.hpp
dependencies64/sfml/include/SFML/Graphics/Image.hpp
dependencies64/sfml/include/SFML/Graphics/Matrix3.hpp [deleted file]
dependencies64/sfml/include/SFML/Graphics/Matrix3.inl [deleted file]
dependencies64/sfml/include/SFML/Graphics/PostFX.hpp [deleted file]
dependencies64/sfml/include/SFML/Graphics/PrimitiveType.hpp [moved from dependencies64/sfml/include/SFML/Window/WindowSettings.hpp with 50% similarity]
dependencies64/sfml/include/SFML/Graphics/Rect.hpp
dependencies64/sfml/include/SFML/Graphics/Rect.inl
dependencies64/sfml/include/SFML/Graphics/RectangleShape.hpp [moved from dependencies64/sfml/include/SFML/System/Win32/Thread.hpp with 50% similarity]
dependencies64/sfml/include/SFML/Graphics/RenderStates.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/RenderTarget.hpp
dependencies64/sfml/include/SFML/Graphics/RenderTexture.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/RenderWindow.hpp
dependencies64/sfml/include/SFML/Graphics/Shader.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Shape.hpp
dependencies64/sfml/include/SFML/Graphics/Sprite.hpp
dependencies64/sfml/include/SFML/Graphics/String.hpp [deleted file]
dependencies64/sfml/include/SFML/Graphics/Text.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Texture.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Transform.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Transformable.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/Vertex.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/VertexArray.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Graphics/View.hpp
dependencies64/sfml/include/SFML/Main.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network.hpp
dependencies64/sfml/include/SFML/Network/Export.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/Ftp.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/Http.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/IpAddress.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/Packet.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/Socket.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/SocketHandle.hpp [moved from dependencies64/sfml/include/SFML/Window/WindowListener.hpp with 62% similarity]
dependencies64/sfml/include/SFML/Network/SocketSelector.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/TcpListener.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/TcpSocket.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Network/UdpSocket.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/OpenGL.hpp [moved from dependencies64/sfml/include/SFML/Window/OpenGL.hpp with 75% similarity]
dependencies64/sfml/include/SFML/System.hpp
dependencies64/sfml/include/SFML/System/Clock.hpp
dependencies64/sfml/include/SFML/System/Err.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/Export.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/InputStream.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/Lock.hpp
dependencies64/sfml/include/SFML/System/Mutex.hpp
dependencies64/sfml/include/SFML/System/NonCopyable.hpp
dependencies64/sfml/include/SFML/System/Randomizer.hpp [deleted file]
dependencies64/sfml/include/SFML/System/Resource.hpp [deleted file]
dependencies64/sfml/include/SFML/System/ResourcePtr.inl [deleted file]
dependencies64/sfml/include/SFML/System/Sleep.hpp
dependencies64/sfml/include/SFML/System/String.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/String.inl [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/Thread.hpp
dependencies64/sfml/include/SFML/System/Thread.inl [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/ThreadLocal.hpp [moved from dependencies64/sfml/include/SFML/System/Win32/Mutex.hpp with 61% similarity]
dependencies64/sfml/include/SFML/System/ThreadLocalPtr.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/ThreadLocalPtr.inl [moved from dependencies64/sfml/include/SFML/System/Resource.inl with 55% similarity]
dependencies64/sfml/include/SFML/System/Time.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/Unicode.hpp [deleted file]
dependencies64/sfml/include/SFML/System/Unicode.inl [deleted file]
dependencies64/sfml/include/SFML/System/Unix/Mutex.hpp [deleted file]
dependencies64/sfml/include/SFML/System/Unix/Thread.hpp [deleted file]
dependencies64/sfml/include/SFML/System/Utf.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/Utf.inl [new file with mode: 0644]
dependencies64/sfml/include/SFML/System/Vector2.hpp
dependencies64/sfml/include/SFML/System/Vector2.inl
dependencies64/sfml/include/SFML/System/Vector3.hpp
dependencies64/sfml/include/SFML/System/Vector3.inl
dependencies64/sfml/include/SFML/Window.hpp
dependencies64/sfml/include/SFML/Window/Context.hpp
dependencies64/sfml/include/SFML/Window/ContextSettings.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/Event.hpp
dependencies64/sfml/include/SFML/Window/Export.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/GlResource.hpp [moved from dependencies64/sfml/include/SFML/Audio/AudioResource.hpp with 67% similarity]
dependencies64/sfml/include/SFML/Window/Input.hpp [deleted file]
dependencies64/sfml/include/SFML/Window/Joystick.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/Keyboard.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/Mouse.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/Sensor.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/Touch.hpp [new file with mode: 0644]
dependencies64/sfml/include/SFML/Window/VideoMode.hpp
dependencies64/sfml/include/SFML/Window/Window.hpp
dependencies64/sfml/include/SFML/Window/WindowHandle.hpp
dependencies64/sfml/include/SFML/Window/WindowStyle.hpp
dependencies64/sfml/lib/sfml-audio-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-audio-d-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-audio-d.lib [deleted file]
dependencies64/sfml/lib/sfml-audio.lib [deleted file]
dependencies64/sfml/lib/sfml-graphics-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-graphics-d-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-graphics-d.lib [deleted file]
dependencies64/sfml/lib/sfml-graphics.lib [deleted file]
dependencies64/sfml/lib/sfml-system-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-system-d-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-system-d.lib [deleted file]
dependencies64/sfml/lib/sfml-system.lib [deleted file]
dependencies64/sfml/lib/sfml-window-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-window-d-2.lib [new file with mode: 0644]
dependencies64/sfml/lib/sfml-window-d.lib [deleted file]
dependencies64/sfml/lib/sfml-window.lib [deleted file]
dependencies64/tbb/bin/tbb.dll
dependencies64/tbb/bin/tbb.pdb
dependencies64/tbb/bin/tbb_debug.dll
dependencies64/tbb/bin/tbb_debug.pdb
dependencies64/tbb/bin/tbb_preview.dll [new file with mode: 0644]
dependencies64/tbb/bin/tbb_preview.pdb [new file with mode: 0644]
dependencies64/tbb/bin/tbb_preview_debug.dll [new file with mode: 0644]
dependencies64/tbb/bin/tbb_preview_debug.pdb [new file with mode: 0644]
dependencies64/tbb/bin/tbbmalloc.dll
dependencies64/tbb/bin/tbbmalloc.pdb
dependencies64/tbb/bin/tbbmalloc_debug.dll
dependencies64/tbb/bin/tbbmalloc_debug.pdb
dependencies64/tbb/bin/tbbmalloc_proxy.dll
dependencies64/tbb/bin/tbbmalloc_proxy.pdb
dependencies64/tbb/bin/tbbmalloc_proxy_debug.dll
dependencies64/tbb/bin/tbbmalloc_proxy_debug.pdb
dependencies64/tbb/include/index.html
dependencies64/tbb/include/serial/tbb/parallel_for.h
dependencies64/tbb/include/serial/tbb/tbb_annotate.h
dependencies64/tbb/include/tbb/aggregator.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/aligned_space.h
dependencies64/tbb/include/tbb/atomic.h
dependencies64/tbb/include/tbb/blocked_range.h
dependencies64/tbb/include/tbb/blocked_range2d.h
dependencies64/tbb/include/tbb/blocked_range3d.h
dependencies64/tbb/include/tbb/cache_aligned_allocator.h
dependencies64/tbb/include/tbb/combinable.h
dependencies64/tbb/include/tbb/compat/condition_variable
dependencies64/tbb/include/tbb/compat/ppl.h
dependencies64/tbb/include/tbb/compat/thread
dependencies64/tbb/include/tbb/compat/tuple
dependencies64/tbb/include/tbb/concurrent_hash_map.h
dependencies64/tbb/include/tbb/concurrent_lru_cache.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/concurrent_priority_queue.h
dependencies64/tbb/include/tbb/concurrent_queue.h
dependencies64/tbb/include/tbb/concurrent_unordered_map.h
dependencies64/tbb/include/tbb/concurrent_unordered_set.h
dependencies64/tbb/include/tbb/concurrent_vector.h
dependencies64/tbb/include/tbb/critical_section.h
dependencies64/tbb/include/tbb/enumerable_thread_specific.h
dependencies64/tbb/include/tbb/flow_graph.h
dependencies64/tbb/include/tbb/index.html
dependencies64/tbb/include/tbb/internal/_aggregator_impl.h
dependencies64/tbb/include/tbb/internal/_concurrent_queue_impl.h
dependencies64/tbb/include/tbb/internal/_concurrent_unordered_impl.h
dependencies64/tbb/include/tbb/internal/_flow_graph_impl.h
dependencies64/tbb/include/tbb/internal/_flow_graph_indexer_impl.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/internal/_flow_graph_item_buffer_impl.h
dependencies64/tbb/include/tbb/internal/_flow_graph_join_impl.h
dependencies64/tbb/include/tbb/internal/_flow_graph_node_impl.h
dependencies64/tbb/include/tbb/internal/_flow_graph_or_impl.h [deleted file]
dependencies64/tbb/include/tbb/internal/_flow_graph_tagged_buffer_impl.h
dependencies64/tbb/include/tbb/internal/_flow_graph_trace_impl.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/internal/_flow_graph_types_impl.h
dependencies64/tbb/include/tbb/internal/_mutex_padding.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/internal/_range_iterator.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/internal/_tbb_strings.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/internal/_tbb_windef.h
dependencies64/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/gcc_armv7.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/gcc_generic.h
dependencies64/tbb/include/tbb/machine/gcc_ia32_common.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/gcc_itsx.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/ibm_aix51.h
dependencies64/tbb/include/tbb/machine/icc_generic.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/linux_common.h
dependencies64/tbb/include/tbb/machine/linux_ia32.h
dependencies64/tbb/include/tbb/machine/linux_ia64.h
dependencies64/tbb/include/tbb/machine/linux_intel64.h
dependencies64/tbb/include/tbb/machine/mac_ppc.h
dependencies64/tbb/include/tbb/machine/macos_common.h
dependencies64/tbb/include/tbb/machine/mic_common.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/msvc_armv7.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/msvc_ia32_common.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/machine/sunos_sparc.h
dependencies64/tbb/include/tbb/machine/windows_api.h
dependencies64/tbb/include/tbb/machine/windows_ia32.h
dependencies64/tbb/include/tbb/machine/windows_intel64.h
dependencies64/tbb/include/tbb/machine/xbox360_ppc.h
dependencies64/tbb/include/tbb/memory_pool.h
dependencies64/tbb/include/tbb/mutex.h
dependencies64/tbb/include/tbb/null_mutex.h
dependencies64/tbb/include/tbb/null_rw_mutex.h
dependencies64/tbb/include/tbb/parallel_do.h
dependencies64/tbb/include/tbb/parallel_for.h
dependencies64/tbb/include/tbb/parallel_for_each.h
dependencies64/tbb/include/tbb/parallel_invoke.h
dependencies64/tbb/include/tbb/parallel_reduce.h
dependencies64/tbb/include/tbb/parallel_scan.h
dependencies64/tbb/include/tbb/parallel_sort.h
dependencies64/tbb/include/tbb/parallel_while.h
dependencies64/tbb/include/tbb/partitioner.h
dependencies64/tbb/include/tbb/pipeline.h
dependencies64/tbb/include/tbb/queuing_mutex.h
dependencies64/tbb/include/tbb/queuing_rw_mutex.h
dependencies64/tbb/include/tbb/reader_writer_lock.h
dependencies64/tbb/include/tbb/recursive_mutex.h
dependencies64/tbb/include/tbb/runtime_loader.h
dependencies64/tbb/include/tbb/scalable_allocator.h
dependencies64/tbb/include/tbb/spin_mutex.h
dependencies64/tbb/include/tbb/spin_rw_mutex.h
dependencies64/tbb/include/tbb/task.h
dependencies64/tbb/include/tbb/task_arena.h [new file with mode: 0644]
dependencies64/tbb/include/tbb/task_group.h
dependencies64/tbb/include/tbb/task_scheduler_init.h
dependencies64/tbb/include/tbb/task_scheduler_observer.h
dependencies64/tbb/include/tbb/tbb.h
dependencies64/tbb/include/tbb/tbb_allocator.h
dependencies64/tbb/include/tbb/tbb_config.h
dependencies64/tbb/include/tbb/tbb_exception.h
dependencies64/tbb/include/tbb/tbb_machine.h
dependencies64/tbb/include/tbb/tbb_profiling.h
dependencies64/tbb/include/tbb/tbb_stddef.h
dependencies64/tbb/include/tbb/tbb_thread.h
dependencies64/tbb/include/tbb/tbbmalloc_proxy.h
dependencies64/tbb/include/tbb/tick_count.h
dependencies64/tbb/lib/irml/irml.lib
dependencies64/tbb/lib/irml/irml_debug.lib
dependencies64/tbb/lib/irml_c/irml.lib [deleted file]
dependencies64/tbb/lib/irml_c/irml_debug.lib [deleted file]
dependencies64/tbb/lib/tbb.def
dependencies64/tbb/lib/tbb.lib
dependencies64/tbb/lib/tbb_debug.lib
dependencies64/tbb/lib/tbb_preview.lib
dependencies64/tbb/lib/tbb_preview_debug.lib
dependencies64/tbb/lib/tbbmalloc.def
dependencies64/tbb/lib/tbbmalloc.lib
dependencies64/tbb/lib/tbbmalloc_debug.lib
dependencies64/tbb/lib/tbbmalloc_proxy.lib
dependencies64/tbb/lib/tbbmalloc_proxy_debug.lib
dependencies64/tbb/lib/tbbproxy.lib
dependencies64/tbb/lib/tbbproxy.pdb [new file with mode: 0644]
dependencies64/tbb/lib/tbbproxy_debug.lib
dependencies64/tbb/lib/tbbproxy_debug.pdb [new file with mode: 0644]
dependencies64/zlib/lib/zlibstat.lib [new file with mode: 0644]

index ea482f092f7a409a26889142b245fa7efb7b8202..1156ce6461899006b333e0e20eb08ddc8432121a 100644 (file)
Binary files a/dependencies64/freeimage/bin/FreeImage.dll and b/dependencies64/freeimage/bin/FreeImage.dll differ
index 380871637616e13724d181c62b2b99d199364236..380235c2b4552c3a22d3fcfd515617263313a593 100644 (file)
Binary files a/dependencies64/freeimage/bin/FreeImaged.dll and b/dependencies64/freeimage/bin/FreeImaged.dll differ
index 6ac0566671fa41edbdd1130805e8d06c88080a98..27551606bc3f5ee6073521da90f4b0ccb221497c 100644 (file)
@@ -29,8 +29,8 @@
 // Version information ------------------------------------------------------
 
 #define FREEIMAGE_MAJOR_VERSION   3
-#define FREEIMAGE_MINOR_VERSION   15
-#define FREEIMAGE_RELEASE_SERIAL  1
+#define FREEIMAGE_MINOR_VERSION   16
+#define FREEIMAGE_RELEASE_SERIAL  0
 
 // Compiler options ---------------------------------------------------------
 
@@ -141,6 +141,8 @@ typedef uint8_t BYTE;
 typedef uint16_t WORD;
 typedef uint32_t DWORD;
 typedef int32_t LONG;
+typedef int64_t INT64;
+typedef uint64_t UINT64;
 #else
 // MS is not C99 ISO compliant
 typedef long BOOL;
@@ -148,6 +150,8 @@ typedef unsigned char BYTE;
 typedef unsigned short WORD;
 typedef unsigned long DWORD;
 typedef long LONG;
+typedef signed __int64 INT64;
+typedef unsigned __int64 UINT64;
 #endif // _MSC_VER
 
 #if (defined(_WIN32) || defined(__WIN32__))
@@ -399,7 +403,9 @@ FI_ENUM(FREE_IMAGE_FORMAT) {
        FIF_JP2         = 31,
        FIF_PFM         = 32,
        FIF_PICT        = 33,
-       FIF_RAW         = 34
+       FIF_RAW         = 34,
+       FIF_WEBP        = 35,
+       FIF_JXR         = 36
 };
 
 /** Image type used in FreeImage.
@@ -525,7 +531,10 @@ FI_ENUM(FREE_IMAGE_MDTYPE) {
        FIDT_FLOAT              = 11,   // 32-bit IEEE floating point 
        FIDT_DOUBLE             = 12,   // 64-bit IEEE floating point 
        FIDT_IFD                = 13,   // 32-bit unsigned integer (offset) 
-       FIDT_PALETTE    = 14    // 32-bit RGBQUAD 
+       FIDT_PALETTE    = 14,   // 32-bit RGBQUAD 
+       FIDT_LONG8              = 16,   // 64-bit unsigned integer 
+       FIDT_SLONG8             = 17,   // 64-bit signed integer
+       FIDT_IFD8               = 18    // 64-bit unsigned integer (offset)
 };
 
 /**
@@ -642,93 +651,99 @@ typedef void (DLL_CALLCONV *FI_InitProc)(Plugin *plugin, int format_id);
 
 // Load / Save flag constants -----------------------------------------------
 
-#define FIF_LOAD_NOPIXELS 0x8000 // loading: load the image header only (not supported by all plugins)
+#define FIF_LOAD_NOPIXELS 0x8000       //! loading: load the image header only (not supported by all plugins, default to full loading)
 
 #define BMP_DEFAULT         0
 #define BMP_SAVE_RLE        1
 #define CUT_DEFAULT         0
 #define DDS_DEFAULT                    0
-#define EXR_DEFAULT                    0               // save data as half with piz-based wavelet compression
-#define EXR_FLOAT                      0x0001  // save data as float instead of as half (not recommended)
-#define EXR_NONE                       0x0002  // save with no compression
-#define EXR_ZIP                                0x0004  // save with zlib compression, in blocks of 16 scan lines
-#define EXR_PIZ                                0x0008  // save with piz-based wavelet compression
-#define EXR_PXR24                      0x0010  // save with lossy 24-bit float compression
-#define EXR_B44                                0x0020  // save with lossy 44% float compression - goes to 22% when combined with EXR_LC
-#define EXR_LC                         0x0040  // save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
+#define EXR_DEFAULT                    0               //! save data as half with piz-based wavelet compression
+#define EXR_FLOAT                      0x0001  //! save data as float instead of as half (not recommended)
+#define EXR_NONE                       0x0002  //! save with no compression
+#define EXR_ZIP                                0x0004  //! save with zlib compression, in blocks of 16 scan lines
+#define EXR_PIZ                                0x0008  //! save with piz-based wavelet compression
+#define EXR_PXR24                      0x0010  //! save with lossy 24-bit float compression
+#define EXR_B44                                0x0020  //! save with lossy 44% float compression - goes to 22% when combined with EXR_LC
+#define EXR_LC                         0x0040  //! save images with one luminance and two chroma channels, rather than as RGB (lossy compression)
 #define FAXG3_DEFAULT          0
 #define GIF_DEFAULT                    0
-#define GIF_LOAD256                    1               // Load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
-#define GIF_PLAYBACK           2               // 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
+#define GIF_LOAD256                    1               //! load the image as a 256 color image with ununsed palette entries, if it's 16 or 2 color
+#define GIF_PLAYBACK           2               //! 'Play' the GIF to generate each frame (as 32bpp) instead of returning raw frame data when loading
 #define HDR_DEFAULT                    0
 #define ICO_DEFAULT         0
-#define ICO_MAKEALPHA          1               // convert to 32bpp and create an alpha channel from the AND-mask when loading
+#define ICO_MAKEALPHA          1               //! convert to 32bpp and create an alpha channel from the AND-mask when loading
 #define IFF_DEFAULT         0
-#define J2K_DEFAULT                    0               // save with a 16:1 rate
-#define JP2_DEFAULT                    0               // save with a 16:1 rate
-#define JPEG_DEFAULT        0          // loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
-#define JPEG_FAST           0x0001     // load the file as fast as possible, sacrificing some quality
-#define JPEG_ACCURATE       0x0002     // load the file with the best quality, sacrificing some speed
-#define JPEG_CMYK                      0x0004  // load separated CMYK "as is" (use | to combine with other load flags)
-#define JPEG_EXIFROTATE                0x0008  // load and rotate according to Exif 'Orientation' tag if available
-#define JPEG_QUALITYSUPERB  0x80       // save with superb quality (100:1)
-#define JPEG_QUALITYGOOD    0x0100     // save with good quality (75:1)
-#define JPEG_QUALITYNORMAL  0x0200     // save with normal quality (50:1)
-#define JPEG_QUALITYAVERAGE 0x0400     // save with average quality (25:1)
-#define JPEG_QUALITYBAD     0x0800     // save with bad quality (10:1)
-#define JPEG_PROGRESSIVE       0x2000  // save as a progressive-JPEG (use | to combine with other save flags)
-#define JPEG_SUBSAMPLING_411 0x1000            // save with high 4x1 chroma subsampling (4:1:1) 
-#define JPEG_SUBSAMPLING_420 0x4000            // save with medium 2x2 medium chroma subsampling (4:2:0) - default value
-#define JPEG_SUBSAMPLING_422 0x8000            // save with low 2x1 chroma subsampling (4:2:2) 
-#define JPEG_SUBSAMPLING_444 0x10000   // save with no chroma subsampling (4:4:4)
-#define JPEG_OPTIMIZE          0x20000         // on saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
-#define JPEG_BASELINE          0x40000         // save basic JPEG, without metadata or any markers
+#define J2K_DEFAULT                    0               //! save with a 16:1 rate
+#define JP2_DEFAULT                    0               //! save with a 16:1 rate
+#define JPEG_DEFAULT        0          //! loading (see JPEG_FAST); saving (see JPEG_QUALITYGOOD|JPEG_SUBSAMPLING_420)
+#define JPEG_FAST           0x0001     //! load the file as fast as possible, sacrificing some quality
+#define JPEG_ACCURATE       0x0002     //! load the file with the best quality, sacrificing some speed
+#define JPEG_CMYK                      0x0004  //! load separated CMYK "as is" (use | to combine with other load flags)
+#define JPEG_EXIFROTATE                0x0008  //! load and rotate according to Exif 'Orientation' tag if available
+#define JPEG_GREYSCALE         0x0010  //! load and convert to a 8-bit greyscale image
+#define JPEG_QUALITYSUPERB  0x80       //! save with superb quality (100:1)
+#define JPEG_QUALITYGOOD    0x0100     //! save with good quality (75:1)
+#define JPEG_QUALITYNORMAL  0x0200     //! save with normal quality (50:1)
+#define JPEG_QUALITYAVERAGE 0x0400     //! save with average quality (25:1)
+#define JPEG_QUALITYBAD     0x0800     //! save with bad quality (10:1)
+#define JPEG_PROGRESSIVE       0x2000  //! save as a progressive-JPEG (use | to combine with other save flags)
+#define JPEG_SUBSAMPLING_411 0x1000            //! save with high 4x1 chroma subsampling (4:1:1) 
+#define JPEG_SUBSAMPLING_420 0x4000            //! save with medium 2x2 medium chroma subsampling (4:2:0) - default value
+#define JPEG_SUBSAMPLING_422 0x8000            //! save with low 2x1 chroma subsampling (4:2:2) 
+#define JPEG_SUBSAMPLING_444 0x10000   //! save with no chroma subsampling (4:4:4)
+#define JPEG_OPTIMIZE          0x20000         //! on saving, compute optimal Huffman coding tables (can reduce a few percent of file size)
+#define JPEG_BASELINE          0x40000         //! save basic JPEG, without metadata or any markers
 #define KOALA_DEFAULT       0
 #define LBM_DEFAULT         0
 #define MNG_DEFAULT         0
 #define PCD_DEFAULT         0
-#define PCD_BASE            1          // load the bitmap sized 768 x 512
-#define PCD_BASEDIV4        2          // load the bitmap sized 384 x 256
-#define PCD_BASEDIV16       3          // load the bitmap sized 192 x 128
+#define PCD_BASE            1          //! load the bitmap sized 768 x 512
+#define PCD_BASEDIV4        2          //! load the bitmap sized 384 x 256
+#define PCD_BASEDIV16       3          //! load the bitmap sized 192 x 128
 #define PCX_DEFAULT         0
 #define PFM_DEFAULT         0
 #define PICT_DEFAULT        0
 #define PNG_DEFAULT         0
-#define PNG_IGNOREGAMMA                1               // loading: avoid gamma correction
-#define PNG_Z_BEST_SPEED                       0x0001  // save using ZLib level 1 compression flag (default value is 6)
-#define PNG_Z_DEFAULT_COMPRESSION      0x0006  // save using ZLib level 6 compression flag (default recommended value)
-#define PNG_Z_BEST_COMPRESSION         0x0009  // save using ZLib level 9 compression flag (default value is 6)
-#define PNG_Z_NO_COMPRESSION           0x0100  // save without ZLib compression
-#define PNG_INTERLACED                         0x0200  // save using Adam7 interlacing (use | to combine with other save flags)
+#define PNG_IGNOREGAMMA                1               //! loading: avoid gamma correction
+#define PNG_Z_BEST_SPEED                       0x0001  //! save using ZLib level 1 compression flag (default value is 6)
+#define PNG_Z_DEFAULT_COMPRESSION      0x0006  //! save using ZLib level 6 compression flag (default recommended value)
+#define PNG_Z_BEST_COMPRESSION         0x0009  //! save using ZLib level 9 compression flag (default value is 6)
+#define PNG_Z_NO_COMPRESSION           0x0100  //! save without ZLib compression
+#define PNG_INTERLACED                         0x0200  //! save using Adam7 interlacing (use | to combine with other save flags)
 #define PNM_DEFAULT         0
-#define PNM_SAVE_RAW        0       // If set the writer saves in RAW format (i.e. P4, P5 or P6)
-#define PNM_SAVE_ASCII      1       // If set the writer saves in ASCII format (i.e. P1, P2 or P3)
+#define PNM_SAVE_RAW        0       //! if set the writer saves in RAW format (i.e. P4, P5 or P6)
+#define PNM_SAVE_ASCII      1       //! if set the writer saves in ASCII format (i.e. P1, P2 or P3)
 #define PSD_DEFAULT         0
-#define PSD_CMYK                       1               // reads tags for separated CMYK (default is conversion to RGB)
-#define PSD_LAB                                2               // reads tags for CIELab (default is conversion to RGB)
+#define PSD_CMYK                       1               //! reads tags for separated CMYK (default is conversion to RGB)
+#define PSD_LAB                                2               //! reads tags for CIELab (default is conversion to RGB)
 #define RAS_DEFAULT         0
-#define RAW_DEFAULT         0          // load the file as linear RGB 48-bit
-#define RAW_PREVIEW                    1               // try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
-#define RAW_DISPLAY                    2               // load the file as RGB 24-bit
-#define RAW_HALFSIZE           4               // output a half-size color image
+#define RAW_DEFAULT         0          //! load the file as linear RGB 48-bit
+#define RAW_PREVIEW                    1               //! try to load the embedded JPEG preview with included Exif Data or default to RGB 24-bit
+#define RAW_DISPLAY                    2               //! load the file as RGB 24-bit
+#define RAW_HALFSIZE           4               //! output a half-size color image
 #define SGI_DEFAULT                    0
 #define TARGA_DEFAULT       0
-#define TARGA_LOAD_RGB888   1       // If set the loader converts RGB555 and ARGB8888 -> RGB888.
-#define TARGA_SAVE_RLE         2               // If set, the writer saves with RLE compression
+#define TARGA_LOAD_RGB888   1       //! if set the loader converts RGB555 and ARGB8888 -> RGB888.
+#define TARGA_SAVE_RLE         2               //! if set, the writer saves with RLE compression
 #define TIFF_DEFAULT        0
-#define TIFF_CMYK                      0x0001  // reads/stores tags for separated CMYK (use | to combine with compression flags)
-#define TIFF_PACKBITS       0x0100  // save using PACKBITS compression
-#define TIFF_DEFLATE        0x0200  // save using DEFLATE compression (a.k.a. ZLIB compression)
-#define TIFF_ADOBE_DEFLATE  0x0400  // save using ADOBE DEFLATE compression
-#define TIFF_NONE           0x0800  // save without any compression
-#define TIFF_CCITTFAX3         0x1000  // save using CCITT Group 3 fax encoding
-#define TIFF_CCITTFAX4         0x2000  // save using CCITT Group 4 fax encoding
-#define TIFF_LZW                       0x4000  // save using LZW compression
-#define TIFF_JPEG                      0x8000  // save using JPEG compression
-#define TIFF_LOGLUV                    0x10000 // save using LogLuv compression
+#define TIFF_CMYK                      0x0001  //! reads/stores tags for separated CMYK (use | to combine with compression flags)
+#define TIFF_PACKBITS       0x0100  //! save using PACKBITS compression
+#define TIFF_DEFLATE        0x0200  //! save using DEFLATE compression (a.k.a. ZLIB compression)
+#define TIFF_ADOBE_DEFLATE  0x0400  //! save using ADOBE DEFLATE compression
+#define TIFF_NONE           0x0800  //! save without any compression
+#define TIFF_CCITTFAX3         0x1000  //! save using CCITT Group 3 fax encoding
+#define TIFF_CCITTFAX4         0x2000  //! save using CCITT Group 4 fax encoding
+#define TIFF_LZW                       0x4000  //! save using LZW compression
+#define TIFF_JPEG                      0x8000  //! save using JPEG compression
+#define TIFF_LOGLUV                    0x10000 //! save using LogLuv compression
 #define WBMP_DEFAULT        0
 #define XBM_DEFAULT                    0
 #define XPM_DEFAULT                    0
+#define WEBP_DEFAULT           0               //! save with good quality (75:1)
+#define WEBP_LOSSLESS          0x100   //! save in lossless mode
+#define JXR_DEFAULT                    0               //! save with quality 80 and no chroma subsampling (4:4:4)
+#define JXR_LOSSLESS           0x0064  //! save lossless
+#define JXR_PROGRESSIVE                0x2000  //! save as a progressive-JXR (use | to combine with other save flags)
 
 // Background filling options ---------------------------------------------------------
 // Constants used in FreeImage_FillBackground and FreeImage_EnlargeCanvas
@@ -971,7 +986,8 @@ DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToRGB16(FIBITMAP *dib);
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToStandardType(FIBITMAP *src, BOOL scale_linear FI_DEFAULT(TRUE));
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ConvertToType(FIBITMAP *src, FREE_IMAGE_TYPE dst_type, BOOL scale_linear FI_DEFAULT(TRUE));
 
-// tone mapping operators
+// Tone mapping operators ---------------------------------------------------
+
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_ToneMapping(FIBITMAP *dib, FREE_IMAGE_TMO tmo, double first_param FI_DEFAULT(0), double second_param FI_DEFAULT(0));
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoDrago03(FIBITMAP *src, double gamma FI_DEFAULT(2.2), double exposure FI_DEFAULT(0));
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_TmoReinhard05(FIBITMAP *src, double intensity FI_DEFAULT(0), double contrast FI_DEFAULT(0));
@@ -988,7 +1004,7 @@ DLL_API DWORD DLL_CALLCONV FreeImage_ZLibGUnzip(BYTE *target, DWORD target_size,
 DLL_API DWORD DLL_CALLCONV FreeImage_ZLibCRC32(DWORD crc, BYTE *source, DWORD source_size);
 
 // --------------------------------------------------------------------------
-// Metadata routines --------------------------------------------------------
+// Metadata routines
 // --------------------------------------------------------------------------
 
 // tag creation / destruction
@@ -1030,7 +1046,21 @@ DLL_API BOOL DLL_CALLCONV FreeImage_CloneMetadata(FIBITMAP *dst, FIBITMAP *src);
 DLL_API const char* DLL_CALLCONV FreeImage_TagToString(FREE_IMAGE_MDMODEL model, FITAG *tag, char *Make FI_DEFAULT(NULL));
 
 // --------------------------------------------------------------------------
-// Image manipulation toolkit -----------------------------------------------
+// JPEG lossless transformation routines
+// --------------------------------------------------------------------------
+
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom);
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom);
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformFromHandle(FreeImageIO* src_io, fi_handle src_handle, FreeImageIO* dst_io, fi_handle dst_handle, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombined(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformCombinedFromMemory(FIMEMORY* src_stream, FIMEMORY* dst_stream, FREE_IMAGE_JPEG_OPERATION operation, int* left, int* top, int* right, int* bottom, BOOL perfect FI_DEFAULT(TRUE));
+
+
+// --------------------------------------------------------------------------
+// Image manipulation toolkit
 // --------------------------------------------------------------------------
 
 // rotation and flipping
@@ -1040,11 +1070,9 @@ DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rotate(FIBITMAP *dib, double angle, con
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_RotateEx(FIBITMAP *dib, double angle, double x_shift, double y_shift, double x_origin, double y_origin, BOOL use_mask);
 DLL_API BOOL DLL_CALLCONV FreeImage_FlipHorizontal(FIBITMAP *dib);
 DLL_API BOOL DLL_CALLCONV FreeImage_FlipVertical(FIBITMAP *dib);
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransform(const char *src_file, const char *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(FALSE));
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGTransformU(const wchar_t *src_file, const wchar_t *dst_file, FREE_IMAGE_JPEG_OPERATION operation, BOOL perfect FI_DEFAULT(FALSE));
 
 // upsampling / downsampling
-DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter);
+DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Rescale(FIBITMAP *dib, int dst_width, int dst_height, FREE_IMAGE_FILTER filter FI_DEFAULT(FILTER_CATMULLROM));
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_MakeThumbnail(FIBITMAP *dib, int max_pixel_size, BOOL convert FI_DEFAULT(TRUE));
 
 // color manipulation routines (point operations)
@@ -1071,8 +1099,6 @@ DLL_API BOOL DLL_CALLCONV FreeImage_SetComplexChannel(FIBITMAP *dst, FIBITMAP *s
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Copy(FIBITMAP *dib, int left, int top, int right, int bottom);
 DLL_API BOOL DLL_CALLCONV FreeImage_Paste(FIBITMAP *dst, FIBITMAP *src, int left, int top, int alpha);
 DLL_API FIBITMAP *DLL_CALLCONV FreeImage_Composite(FIBITMAP *fg, BOOL useFileBkg FI_DEFAULT(FALSE), RGBQUAD *appBkColor FI_DEFAULT(NULL), FIBITMAP *bg FI_DEFAULT(NULL));
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCrop(const char *src_file, const char *dst_file, int left, int top, int right, int bottom);
-DLL_API BOOL DLL_CALLCONV FreeImage_JPEGCropU(const wchar_t *src_file, const wchar_t *dst_file, int left, int top, int right, int bottom);
 DLL_API BOOL DLL_CALLCONV FreeImage_PreMultiplyWithAlpha(FIBITMAP *dib);
 
 // background filling routines
index 2d747519d9d947b88726a6bcada7f3939d3277cd..1e5974203fe20315a3b2adc4b6e5ffd2a11fc67d 100644 (file)
Binary files a/dependencies64/freeimage/lib/FreeImage.lib and b/dependencies64/freeimage/lib/FreeImage.lib differ
index 4a1e813a2abff417b1a48260af20b537f060d9c6..6d23495691e3215bd9fea2df89a6faecc80ae6c2 100644 (file)
Binary files a/dependencies64/freeimage/lib/FreeImaged.lib and b/dependencies64/freeimage/lib/FreeImaged.lib differ
index edf9187ff717f2caf9dd8109bd381b020ce0aa9b..0956036c866c7c44fa07edde3d761e6ce1224cfe 100644 (file)
Binary files a/dependencies64/gtest/lib/gtest.lib and b/dependencies64/gtest/lib/gtest.lib differ
index 9b7d1e54d8a571fb1e6fce0ad3b1576b724fcba1..17ff697c91406bf41866610c758a70f96cc3d17b 100644 (file)
Binary files a/dependencies64/gtest/lib/gtestd.lib and b/dependencies64/gtest/lib/gtestd.lib differ
diff --git a/dependencies64/sfml/extlibs/lib/freetype.lib b/dependencies64/sfml/extlibs/lib/freetype.lib
new file mode 100644 (file)
index 0000000..34eb0fb
Binary files /dev/null and b/dependencies64/sfml/extlibs/lib/freetype.lib differ
diff --git a/dependencies64/sfml/extlibs/lib/freetype248.lib b/dependencies64/sfml/extlibs/lib/freetype248.lib
deleted file mode 100644 (file)
index 1ba7df5..0000000
Binary files a/dependencies64/sfml/extlibs/lib/freetype248.lib and /dev/null differ
diff --git a/dependencies64/sfml/extlibs/lib/freetype248_D.lib b/dependencies64/sfml/extlibs/lib/freetype248_D.lib
deleted file mode 100644 (file)
index c7a6972..0000000
Binary files a/dependencies64/sfml/extlibs/lib/freetype248_D.lib and /dev/null differ
diff --git a/dependencies64/sfml/extlibs/lib/glew.lib b/dependencies64/sfml/extlibs/lib/glew.lib
new file mode 100644 (file)
index 0000000..82b7d50
Binary files /dev/null and b/dependencies64/sfml/extlibs/lib/glew.lib differ
diff --git a/dependencies64/sfml/extlibs/lib/jpeg.lib b/dependencies64/sfml/extlibs/lib/jpeg.lib
new file mode 100644 (file)
index 0000000..d9aa1b4
Binary files /dev/null and b/dependencies64/sfml/extlibs/lib/jpeg.lib differ
diff --git a/dependencies64/sfml/extlibs/lib/openal32.lib b/dependencies64/sfml/extlibs/lib/openal32.lib
new file mode 100644 (file)
index 0000000..b030b32
Binary files /dev/null and b/dependencies64/sfml/extlibs/lib/openal32.lib differ
diff --git a/dependencies64/sfml/extlibs/lib/sndfile.lib b/dependencies64/sfml/extlibs/lib/sndfile.lib
new file mode 100644 (file)
index 0000000..ceed966
Binary files /dev/null and b/dependencies64/sfml/extlibs/lib/sndfile.lib differ
index 2dc1b2f338263888a605d0405e0bab99ad4ecb7d..15a079f675ad08f9f2f1b8c8f8c9eb46eda00bbe 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 
 #include <SFML/System.hpp>
 #include <SFML/Audio/Listener.hpp>
+#include <SFML/Audio/Music.hpp>
 #include <SFML/Audio/Sound.hpp>
 #include <SFML/Audio/SoundBuffer.hpp>
+#include <SFML/Audio/SoundBufferRecorder.hpp>
+#include <SFML/Audio/SoundRecorder.hpp>
 #include <SFML/Audio/SoundStream.hpp>
 
 
 #endif // SFML_AUDIO_HPP
+
+////////////////////////////////////////////////////////////
+/// \defgroup audio Audio module
+///
+/// Sounds, streaming (musics or custom sources), recording,
+/// spatialization.
+/// 
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Audio/Export.hpp b/dependencies64/sfml/include/SFML/Audio/Export.hpp
new file mode 100644 (file)
index 0000000..0cd99ac
--- /dev/null
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_AUDIO_EXPORT_HPP
+#define SFML_AUDIO_EXPORT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_AUDIO_EXPORTS)
+
+    #define SFML_AUDIO_API SFML_API_EXPORT
+
+#else
+
+    #define SFML_AUDIO_API SFML_API_IMPORT
+
+#endif
+
+
+#endif // SFML_AUDIO_EXPORT_HPP
index 1e99a2d7a69cf2afc47f340092a988d10f90474b..2ab203ef4e1a08a376611c080f5e7add862424b9 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/Audio/Export.hpp>
 #include <SFML/System/Vector3.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Listener is a global interface for defining the audio
-/// listener properties ; the audio listener is the point in
-/// the scene from where all the sounds are heard
+/// \brief The audio listener is the point in the scene
+///        from where all the sounds are heard
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Listener
+class SFML_AUDIO_API Listener
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Change the global volume of all the sounds.
-    /// The default volume is 100
+    /// \brief Change the global volume of all the sounds and musics
     ///
-    /// \param Volume : New global volume, in the range [0, 100]
+    /// The volume is a number between 0 and 100; it is combined with
+    /// the individual volume of each sound / music.
+    /// The default value for the volume is 100 (maximum).
+    ///
+    /// \param volume New global volume, in the range [0, 100]
+    ///
+    /// \see getGlobalVolume
     ///
     ////////////////////////////////////////////////////////////
-    static void SetGlobalVolume(float Volume);
+    static void setGlobalVolume(float volume);
 
     ////////////////////////////////////////////////////////////
-    /// Get the current value of the global volume of all the sounds
+    /// \brief Get the current value of the global volume
     ///
     /// \return Current global volume, in the range [0, 100]
     ///
+    /// \see setGlobalVolume
+    ///
     ////////////////////////////////////////////////////////////
-    static float GetGlobalVolume();
+    static float getGlobalVolume();
 
     ////////////////////////////////////////////////////////////
-    /// Change the position of the listener (take 3 values).
-    /// The default position is (0, 0, 0)
+    /// \brief Set the position of the listener in the scene
+    ///
+    /// The default listener's position is (0, 0, 0).
+    ///
+    /// \param x X coordinate of the listener's position
+    /// \param y Y coordinate of the listener's position
+    /// \param z Z coordinate of the listener's position
     ///
-    /// \param X, Y, Z : Position of the listener in the world
+    /// \see getPosition, setDirection
     ///
     ////////////////////////////////////////////////////////////
-    static void SetPosition(float X, float Y, float Z);
+    static void setPosition(float x, float y, float z);
 
     ////////////////////////////////////////////////////////////
-    /// Change the position of the listener (take a 3D vector).
-    /// The default position is (0, 0, 0)
+    /// \brief Set the position of the listener in the scene
     ///
-    /// \param Position : Position of the listener in the world
+    /// The default listener's position is (0, 0, 0).
+    ///
+    /// \param position New listener's position
+    ///
+    /// \see getPosition, setDirection
     ///
     ////////////////////////////////////////////////////////////
-    static void SetPosition(const Vector3f& Position);
+    static void setPosition(const Vector3f& position);
 
     ////////////////////////////////////////////////////////////
-    /// Get the current position of the listener
+    /// \brief Get the current position of the listener in the scene
+    ///
+    /// \return Listener's position
     ///
-    /// \return Position of the listener in the world
+    /// \see setPosition
     ///
     ////////////////////////////////////////////////////////////
-    static Vector3f GetPosition();
+    static Vector3f getPosition();
 
     ////////////////////////////////////////////////////////////
-    /// Change the orientation of the listener (the point
-    /// he must look at) (take 3 values).
-    /// The default target is (0, 0, -1)
+    /// \brief Set the forward vector of the listener in the scene
+    ///
+    /// The direction (also called "at vector") is the vector
+    /// pointing forward from the listener's perspective. Together
+    /// with the up vector, it defines the 3D orientation of the
+    /// listener in the scene. The direction vector doesn't
+    /// have to be normalized.
+    /// The default listener's direction is (0, 0, -1).
+    ///
+    /// \param x X coordinate of the listener's direction
+    /// \param y Y coordinate of the listener's direction
+    /// \param z Z coordinate of the listener's direction
     ///
-    /// \param X, Y, Z : Position of the point the listener must look at
+    /// \see getDirection, setUpVector, setPosition
     ///
     ////////////////////////////////////////////////////////////
-    static void SetTarget(float X, float Y, float Z);
+    static void setDirection(float x, float y, float z);
 
     ////////////////////////////////////////////////////////////
-    /// Change the orientation of the listener (the point
-    /// he must look at) (take a 3D vector).
-    /// The default target is (0, 0, -1)
+    /// \brief Set the forward vector of the listener in the scene
     ///
-    /// \param Target : Position of the point the listener must look at
+    /// The direction (also called "at vector") is the vector
+    /// pointing forward from the listener's perspective. Together
+    /// with the up vector, it defines the 3D orientation of the
+    /// listener in the scene. The direction vector doesn't
+    /// have to be normalized.
+    /// The default listener's direction is (0, 0, -1).
+    ///
+    /// \param direction New listener's direction
+    ///
+    /// \see getDirection, setUpVector, setPosition
     ///
     ////////////////////////////////////////////////////////////
-    static void SetTarget(const Vector3f& Target);
+    static void setDirection(const Vector3f& direction);
 
     ////////////////////////////////////////////////////////////
-    /// Get the current orientation of the listener (the point
-    /// he's looking at)
+    /// \brief Get the current forward vector of the listener in the scene
+    ///
+    /// \return Listener's forward vector (not normalized)
     ///
-    /// \return : Position of the point the listener is looking at
+    /// \see setDirection
     ///
     ////////////////////////////////////////////////////////////
-    static Vector3f GetTarget();
+    static Vector3f getDirection();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the upward vector of the listener in the scene
+    ///
+    /// The up vector is the vector that points upward from the
+    /// listener's perspective. Together with the direction, it
+    /// defines the 3D orientation of the listener in the scene.
+    /// The up vector doesn't have to be normalized.
+    /// The default listener's up vector is (0, 1, 0). It is usually
+    /// not necessary to change it, especially in 2D scenarios.
+    ///
+    /// \param x X coordinate of the listener's up vector
+    /// \param y Y coordinate of the listener's up vector
+    /// \param z Z coordinate of the listener's up vector
+    ///
+    /// \see getUpVector, setDirection, setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    static void setUpVector(float x, float y, float z);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the upward vector of the listener in the scene
+    ///
+    /// The up vector is the vector that points upward from the
+    /// listener's perspective. Together with the direction, it
+    /// defines the 3D orientation of the listener in the scene.
+    /// The up vector doesn't have to be normalized.
+    /// The default listener's up vector is (0, 1, 0). It is usually
+    /// not necessary to change it, especially in 2D scenarios.
+    ///
+    /// \param upVector New listener's up vector
+    ///
+    /// \see getUpVector, setDirection, setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    static void setUpVector(const Vector3f& upVector);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current upward vector of the listener in the scene
+    ///
+    /// \return Listener's upward vector (not normalized)
+    ///
+    /// \see setUpVector
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector3f getUpVector();
 };
 
 } // namespace sf
 
 
 #endif // SFML_LISTENER_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Listener
+/// \ingroup audio
+///
+/// The audio listener defines the global properties of the
+/// audio environment, it defines where and how sounds and musics
+/// are heard. If sf::View is the eyes of the user, then sf::Listener
+/// is his ears (by the way, they are often linked together --
+/// same position, orientation, etc.). 
+///
+/// sf::Listener is a simple interface, which allows to setup the
+/// listener in the 3D audio environment (position, direction and
+/// up vector), and to adjust the global volume.
+///
+/// Because the listener is unique in the scene, sf::Listener only
+/// contains static functions and doesn't have to be instantiated.
+///
+/// Usage example:
+/// \code
+/// // Move the listener to the position (1, 0, -5)
+/// sf::Listener::setPosition(1, 0, -5);
+///
+/// // Make it face the right axis (1, 0, 0)
+/// sf::Listener::setDirection(1, 0, 0);
+///
+/// // Reduce the global volume
+/// sf::Listener::setGlobalVolume(50);
+/// \endcode
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Audio/Music.hpp b/dependencies64/sfml/include/SFML/Audio/Music.hpp
new file mode 100644 (file)
index 0000000..99b7dac
--- /dev/null
@@ -0,0 +1,228 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_MUSIC_HPP
+#define SFML_MUSIC_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Audio/Export.hpp>
+#include <SFML/Audio/SoundStream.hpp>
+#include <SFML/System/Mutex.hpp>
+#include <SFML/System/Time.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+namespace priv
+{
+    class SoundFile;
+}
+
+class InputStream;
+
+////////////////////////////////////////////////////////////
+/// \brief Streamed music played from an audio file
+///
+////////////////////////////////////////////////////////////
+class SFML_AUDIO_API Music : public SoundStream
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    Music();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    ~Music();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Open a music from an audio file
+    ///
+    /// This function doesn't start playing the music (call play()
+    /// to do so).
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    ///
+    /// \param filename Path of the music file to open
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see openFromMemory, openFromStream
+    ///
+    ////////////////////////////////////////////////////////////
+    bool openFromFile(const std::string& filename);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Open a music from an audio file in memory
+    ///
+    /// This function doesn't start playing the music (call play()
+    /// to do so).
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    /// Since the music is not loaded completely but rather streamed
+    /// continuously, the \a data must remain available as long as the
+    /// music is playing (i.e. you can't deallocate it right after calling
+    /// this function).
+    ///
+    /// \param data        Pointer to the file data in memory
+    /// \param sizeInBytes Size of the data to load, in bytes
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see openFromFile, openFromStream
+    ///
+    ////////////////////////////////////////////////////////////
+    bool openFromMemory(const void* data, std::size_t sizeInBytes);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Open a music from an audio file in a custom stream
+    ///
+    /// This function doesn't start playing the music (call play()
+    /// to do so).
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    /// Since the music is not loaded completely but rather streamed
+    /// continuously, the \a stream must remain alive as long as the
+    /// music is playing (i.e. you can't destroy it right after calling
+    /// this function).
+    ///
+    /// \param stream Source stream to read from
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see openFromFile, openFromMemory
+    ///
+    ////////////////////////////////////////////////////////////
+    bool openFromStream(InputStream& stream);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the total duration of the music
+    ///
+    /// \return Music duration
+    ///
+    ////////////////////////////////////////////////////////////
+    Time getDuration() const;
+
+protected:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Request a new chunk of audio samples from the stream source
+    ///
+    /// This function fills the chunk from the next samples
+    /// to read from the audio file.
+    ///
+    /// \param data Chunk of data to fill
+    ///
+    /// \return True to continue playback, false to stop
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool onGetData(Chunk& data);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change the current playing position in the stream source
+    ///
+    /// \param timeOffset New playing position, from the beginning of the music
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual void onSeek(Time timeOffset);
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Initialize the internal state after loading a new music
+    ///
+    ////////////////////////////////////////////////////////////
+    void initialize();
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    priv::SoundFile*   m_file;     ///< Sound file
+    Time               m_duration; ///< Music duration
+    std::vector<Int16> m_samples;  ///< Temporary buffer of samples
+    Mutex              m_mutex;    ///< Mutex protecting the data
+};
+
+} // namespace sf
+
+
+#endif // SFML_MUSIC_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Music
+/// \ingroup audio
+///
+/// Music objects are sounds that are streamed rather than
+/// completely loaded in memory. This is especially useful for
+/// compressed music that usually takes hundreds of MB when it is
+/// uncompressed: by streaming it instead of loading it entirely,
+/// you avoid saturating the memory and have almost no loading delay.
+///
+/// Apart from that, sf::Music has almost the same features as
+/// the sf::SoundBuffer / sf::Sound pair: you can play/pause/stop
+/// it, request its parameters (channels, sample rate), change
+/// the way it is played (pitch, volume, 3D position, ...), etc.
+///
+/// As a sound stream, a music is played in its own thread in order
+/// not to block the rest of the program. This means that you can
+/// leave the music alone after calling play(), it will manage itself
+/// very well.
+///
+/// Usage example:
+/// \code
+/// // Declare a new music
+/// sf::Music music;
+///
+/// // Open it from an audio file
+/// if (!music.openFromFile("music.ogg"))
+/// {
+///     // error...
+/// }
+///
+/// // Change some parameters
+/// music.setPosition(0, 1, 10); // change its 3D position
+/// music.setPitch(2);           // increase the pitch
+/// music.setVolume(50);         // reduce the volume
+/// music.setLoop(true);         // make it loop
+///
+/// // Play it
+/// music.play();
+/// \endcode
+///
+/// \see sf::Sound, sf::SoundStream
+///
+////////////////////////////////////////////////////////////
index 4ad8a326233adf79df9707141764c8637bd640c3..dbd586922ce4b92214fde0353506c43122ca08b3 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
@@ -28,9 +28,9 @@
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/Resource.hpp>
-#include <SFML/System/Vector3.hpp>
-#include <SFML/Audio/AudioResource.hpp>
+#include <SFML/Audio/Export.hpp>
+#include <SFML/Audio/SoundSource.hpp>
+#include <SFML/System/Time.hpp>
 #include <cstdlib>
 
 
@@ -39,276 +39,226 @@ namespace sf
 class SoundBuffer;
 
 ////////////////////////////////////////////////////////////
-/// Sound defines the properties of a sound such as position,
-/// volume, pitch, etc.
+/// \brief Regular sound that can be played in the audio environment
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Sound : public AudioResource
+class SFML_AUDIO_API Sound : public SoundSource
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Enumeration of the sound states
-    ////////////////////////////////////////////////////////////
-    enum Status
-    {
-        Stopped, ///< Sound is not playing
-        Paused,  ///< Sound is paused
-        Playing  ///< Sound is playing
-    };
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
     ///
     ////////////////////////////////////////////////////////////
     Sound();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the sound from its parameters
+    /// \brief Construct the sound with a buffer
     ///
-    /// \param Buffer :   Sound buffer to play (NULL by default)
-    /// \param Loop :     Loop flag (false by default)
-    /// \param Pitch :    Value of the pitch (1 by default)
-    /// \param Volume :   Volume (100 by default)
-    /// \param Position : Position (0, 0, 0 by default)
+    /// \param buffer Sound buffer containing the audio data to play with the sound
     ///
     ////////////////////////////////////////////////////////////
-    explicit Sound(const SoundBuffer& Buffer, bool Loop = false, float Pitch = 1.f, float Volume = 100.f, const Vector3f& Position = Vector3f(0, 0, 0));
+    explicit Sound(const SoundBuffer& buffer);
 
     ////////////////////////////////////////////////////////////
-    /// Copy constructor
+    /// \brief Copy constructor
     ///
-    /// \param Copy : Instance to copy
+    /// \param copy Instance to copy
     ///
     ////////////////////////////////////////////////////////////
-    Sound(const Sound& Copy);
+    Sound(const Sound& copy);
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
     ~Sound();
 
     ////////////////////////////////////////////////////////////
-    /// Play the sound
+    /// \brief Start or resume playing the sound
     ///
-    ////////////////////////////////////////////////////////////
-    void Play();
-
-    ////////////////////////////////////////////////////////////
-    /// Pause the sound
+    /// This function starts the stream if it was stopped, resumes
+    /// it if it was paused, and restarts it from beginning if it
+    /// was it already playing.
+    /// This function uses its own thread so that it doesn't block
+    /// the rest of the program while the sound is played.
     ///
-    ////////////////////////////////////////////////////////////
-    void Pause();
-
-    ////////////////////////////////////////////////////////////
-    /// Stop the sound
+    /// \see pause, stop
     ///
     ////////////////////////////////////////////////////////////
-    void Stop();
+    void play();
 
     ////////////////////////////////////////////////////////////
-    /// Set the source buffer
+    /// \brief Pause the sound
     ///
-    /// \param Buffer : New sound buffer to bind to the sound
+    /// This function pauses the sound if it was playing,
+    /// otherwise (sound already paused or stopped) it has no effect.
     ///
-    ////////////////////////////////////////////////////////////
-    void SetBuffer(const SoundBuffer& Buffer);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the sound loop state.
-    /// This parameter is disabled by default
-    ///
-    /// \param Loop : True to play in loop, false to play once
+    /// \see play, stop
     ///
     ////////////////////////////////////////////////////////////
-    void SetLoop(bool Loop);
+    void pause();
 
     ////////////////////////////////////////////////////////////
-    /// Set the sound pitch.
-    /// The default pitch is 1
-    ///
-    /// \param Pitch : New pitch
+    /// \brief stop playing the sound
     ///
-    ////////////////////////////////////////////////////////////
-    void SetPitch(float Pitch);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the sound volume.
-    /// The default volume is 100
+    /// This function stops the sound if it was playing or paused,
+    /// and does nothing if it was already stopped.
+    /// It also resets the playing position (unlike pause()).
     ///
-    /// \param Volume : Volume (in range [0, 100])
+    /// \see play, pause
     ///
     ////////////////////////////////////////////////////////////
-    void SetVolume(float Volume);
+    void stop();
 
     ////////////////////////////////////////////////////////////
-    /// Set the sound position (take 3 values).
-    /// The default position is (0, 0, 0)
+    /// \brief Set the source buffer containing the audio data to play
     ///
-    /// \param X, Y, Z : Position of the sound in the world
+    /// It is important to note that the sound buffer is not copied,
+    /// thus the sf::SoundBuffer instance must remain alive as long
+    /// as it is attached to the sound.
     ///
-    ////////////////////////////////////////////////////////////
-    void SetPosition(float X, float Y, float Z);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the sound position (take a 3D vector).
-    /// The default position is (0, 0, 0)
+    /// \param buffer Sound buffer to attach to the sound
     ///
-    /// \param Position : Position of the sound in the world
+    /// \see getBuffer
     ///
     ////////////////////////////////////////////////////////////
-    void SetPosition(const Vector3f& Position);
+    void setBuffer(const SoundBuffer& buffer);
 
     ////////////////////////////////////////////////////////////
-    /// Make the sound's position relative to the listener's
-    /// position, or absolute.
-    /// The default value is false (absolute)
+    /// \brief Set whether or not the sound should loop after reaching the end
     ///
-    /// \param Relative : True to set the position relative, false to set it absolute
+    /// If set, the sound will restart from beginning after
+    /// reaching the end and so on, until it is stopped or
+    /// setLoop(false) is called.
+    /// The default looping state for sound is false.
     ///
-    ////////////////////////////////////////////////////////////
-    void SetRelativeToListener(bool Relative);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the minimum distance - closer than this distance,
-    /// the listener will hear the sound at its maximum volume.
-    /// The default minimum distance is 1.0
+    /// \param loop True to play in loop, false to play once
     ///
-    /// \param MinDistance : New minimum distance for the sound
+    /// \see getLoop
     ///
     ////////////////////////////////////////////////////////////
-    void SetMinDistance(float MinDistance);
+    void setLoop(bool loop);
 
     ////////////////////////////////////////////////////////////
-    /// Set the attenuation factor - the higher the attenuation, the
-    /// more the sound will be attenuated with distance from listener.
-    /// The default attenuation factor 1.0
+    /// \brief Change the current playing position of the sound
     ///
-    /// \param Attenuation : New attenuation factor for the sound
+    /// The playing position can be changed when the sound is
+    /// either paused or playing. Changing the playing position
+    /// when the sound is stopped has no effect, since playing
+    /// the sound will reset its position.
     ///
-    ////////////////////////////////////////////////////////////
-    void SetAttenuation(float Attenuation);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the current playing position of the sound
+    /// \param timeOffset New playing position, from the beginning of the sound
     ///
-    /// \param TimeOffset : New playing position, expressed in seconds
+    /// \see getPlayingOffset
     ///
     ////////////////////////////////////////////////////////////
-    void SetPlayingOffset(float TimeOffset);
+    void setPlayingOffset(Time timeOffset);
 
     ////////////////////////////////////////////////////////////
-    /// Get the source buffer
+    /// \brief Get the audio buffer attached to the sound
     ///
-    /// \return Sound buffer bound to the sound (can be NULL)
+    /// \return Sound buffer attached to the sound (can be NULL)
     ///
     ////////////////////////////////////////////////////////////
-    const SoundBuffer* GetBuffer() const;
+    const SoundBuffer* getBuffer() const;
 
     ////////////////////////////////////////////////////////////
-    /// Tell whether or not the sound is looping
+    /// \brief Tell whether or not the sound is in loop mode
     ///
     /// \return True if the sound is looping, false otherwise
     ///
-    ////////////////////////////////////////////////////////////
-    bool GetLoop() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the pitch
-    ///
-    /// \return Pitch value
+    /// \see setLoop
     ///
     ////////////////////////////////////////////////////////////
-    float GetPitch() const;
+    bool getLoop() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the volume
+    /// \brief Get the current playing position of the sound
     ///
-    /// \return Volume value (in range [1, 100])
+    /// \return Current playing position, from the beginning of the sound
     ///
-    ////////////////////////////////////////////////////////////
-    float GetVolume() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the sound position
-    ///
-    /// \return Position of the sound in the world
+    /// \see setPlayingOffset
     ///
     ////////////////////////////////////////////////////////////
-    Vector3f GetPosition() const;
+    Time getPlayingOffset() const;
 
     ////////////////////////////////////////////////////////////
-    /// Tell if the sound's position is relative to the listener's
-    /// position, or if it's absolute
-    ///
-    /// \return True if the position is relative, false if it's absolute
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsRelativeToListener() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the minimum distance
-    ///
-    /// \return Minimum distance for the sound
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetMinDistance() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the attenuation factor
-    ///
-    /// \return Attenuation factor of the sound
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetAttenuation() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the status of the sound (stopped, paused, playing)
+    /// \brief Get the current status of the sound (stopped, paused, playing)
     ///
     /// \return Current status of the sound
     ///
     ////////////////////////////////////////////////////////////
-    Status GetStatus() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the current playing position of the sound
-    ///
-    /// \return Current playing position, expressed in seconds
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetPlayingOffset() const;
+    Status getStatus() const;
 
     ////////////////////////////////////////////////////////////
-    /// Assignment operator
+    /// \brief Overload of assignment operator
     ///
-    /// \param Other : Instance to assign
+    /// \param right Instance to assign
     ///
-    /// \return Reference to the sound
+    /// \return Reference to self
     ///
     ////////////////////////////////////////////////////////////
-    Sound& operator =(const Sound& Other);
+    Sound& operator =(const Sound& right);
 
     ////////////////////////////////////////////////////////////
-    /// Reset the internal buffer
+    /// \brief Reset the internal buffer of the sound
     ///
     /// This function is for internal use only, you don't have
-    /// to use it.
+    /// to use it. It is called by the sf::SoundBuffer that
+    /// this sound uses, when it is destroyed in order to prevent
+    /// the sound from using a dead buffer.
     ///
     ////////////////////////////////////////////////////////////
-    void ResetBuffer();
+    void resetBuffer();
 
-private :
-
-    friend class SoundStream;
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    unsigned int             mySource; ///< OpenAL source identifier
-    ResourcePtr<SoundBuffer> myBuffer; ///< Sound buffer bound to the source
+    const SoundBuffer* m_buffer; ///< Sound buffer bound to the source
 };
 
 } // namespace sf
 
 
 #endif // SFML_SOUND_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Sound
+/// \ingroup audio
+///
+/// sf::Sound is the class to use to play sounds.
+/// It provides:
+/// \li Control (play, pause, stop)
+/// \li Ability to modify output parameters in real-time (pitch, volume, ...)
+/// \li 3D spatial features (position, attenuation, ...).
+///
+/// sf::Sound is perfect for playing short sounds that can
+/// fit in memory and require no latency, like foot steps or
+/// gun shots. For longer sounds, like background musics
+/// or long speeches, rather see sf::Music (which is based
+/// on streaming).
+///
+/// In order to work, a sound must be given a buffer of audio
+/// data to play. Audio data (samples) is stored in sf::SoundBuffer,
+/// and attached to a sound with the setBuffer() function.
+/// The buffer object attached to a sound must remain alive
+/// as long as the sound uses it. Note that multiple sounds
+/// can use the same sound buffer at the same time.
+///
+/// Usage example:
+/// \code
+/// sf::SoundBuffer buffer;
+/// buffer.loadFromFile("sound.wav");
+///
+/// sf::Sound sound;
+/// sound.setBuffer(buffer);
+/// sound.play();
+/// \endcode
+///
+/// \see sf::SoundBuffer, sf::Music
+///
+////////////////////////////////////////////////////////////
index 712a2d82993e5cd5886d23e8474d85e009e66167..392b4617ab36dbad6e2c67e8623787029b46a043 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
@@ -28,8 +28,8 @@
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/Resource.hpp>
-#include <SFML/Audio/AudioResource.hpp>
+#include <SFML/Audio/Export.hpp>
+#include <SFML/System/Time.hpp>
 #include <string>
 #include <vector>
 #include <set>
 
 namespace sf
 {
+namespace priv
+{
+    class SoundFile;
+}
+
 class Sound;
+class InputStream;
 
 ////////////////////////////////////////////////////////////
-/// SoundBuffer is the low-level for loading and manipulating
-/// sound buffers
+/// \brief Storage for audio samples defining a sound
+///
 ////////////////////////////////////////////////////////////
-class SFML_API SoundBuffer : public AudioResource, public Resource<SoundBuffer>
+class SFML_AUDIO_API SoundBuffer
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
     ///
     ////////////////////////////////////////////////////////////
     SoundBuffer();
 
     ////////////////////////////////////////////////////////////
-    /// Copy constructor
+    /// \brief Copy constructor
     ///
-    /// \param Copy : Instance to copy
+    /// \param copy Instance to copy
     ///
     ////////////////////////////////////////////////////////////
-    SoundBuffer(const SoundBuffer& Copy);
+    SoundBuffer(const SoundBuffer& copy);
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
     ~SoundBuffer();
 
     ////////////////////////////////////////////////////////////
-    /// Load the sound buffer from an array of samples - assumed format for
-    /// samples is 16 bits signed integer
+    /// \brief Load the sound buffer from a file
+    ///
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    ///
+    /// \param filename Path of the sound file to load
     ///
-    /// \param Samples :       Pointer to the samples in memory
-    /// \param SamplesCount :  Number of samples pointed by Samples
-    /// \param ChannelsCount : Number of channels (1 = mono, 2 = stereo, ...)
-    /// \param SampleRate :    Frequency (number of samples to play per second)
+    /// \return True if loading succeeded, false if it failed
     ///
-    /// \return True if loading has been successful
+    /// \see loadFromMemory, loadFromStream, loadFromSamples, saveToFile
     ///
     ////////////////////////////////////////////////////////////
-    bool LoadFromSamples(const Int16* Samples, std::size_t SamplesCount, unsigned int ChannelsCount, unsigned int SampleRate);
-       
-       ////////////////////////////////////////////////////////////
-    /// Return the sound samples
+    bool loadFromFile(const std::string& filename);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load the sound buffer from a file in memory
+    ///
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    ///
+    /// \param data        Pointer to the file data in memory
+    /// \param sizeInBytes Size of the data to load, in bytes
     ///
-    /// \return Pointer to the array of sound samples, in 16 bits signed integer format
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromStream, loadFromSamples
     ///
     ////////////////////////////////////////////////////////////
-    const Int16* GetSamples() const;
+    bool loadFromMemory(const void* data, std::size_t sizeInBytes);
 
     ////////////////////////////////////////////////////////////
-    /// Return the samples count
+    /// \brief Load the sound buffer from a custom stream
+    ///
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    ///
+    /// \param stream Source stream to read from
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromMemory, loadFromSamples
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromStream(InputStream& stream);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load the sound buffer from an array of audio samples
+    ///
+    /// The assumed format of the audio samples is 16 bits signed integer
+    /// (sf::Int16).
+    ///
+    /// \param samples      Pointer to the array of samples in memory
+    /// \param sampleCount  Number of samples in the array
+    /// \param channelCount Number of channels (1 = mono, 2 = stereo, ...)
+    /// \param sampleRate   Sample rate (number of samples to play per second)
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromMemory, saveToFile
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromSamples(const Int16* samples, std::size_t sampleCount, unsigned int channelCount, unsigned int sampleRate);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Save the sound buffer to an audio file
+    ///
+    /// Here is a complete list of all the supported audio formats:
+    /// ogg, wav, flac, aiff, au, raw, paf, svx, nist, voc, ircam,
+    /// w64, mat4, mat5 pvf, htk, sds, avr, sd2, caf, wve, mpc2k, rf64.
+    ///
+    /// \param filename Path of the sound file to write
+    ///
+    /// \return True if saving succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromMemory, loadFromSamples
+    ///
+    ////////////////////////////////////////////////////////////
+    bool saveToFile(const std::string& filename) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the array of audio samples stored in the buffer
+    ///
+    /// The format of the returned samples is 16 bits signed integer
+    /// (sf::Int16). The total number of samples in this array
+    /// is given by the getSampleCount() function.
+    ///
+    /// \return Read-only pointer to the array of sound samples
+    ///
+    /// \see getSampleCount
+    ///
+    ////////////////////////////////////////////////////////////
+    const Int16* getSamples() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the number of samples stored in the buffer
+    ///
+    /// The array of samples can be accessed with the getSamples()
+    /// function.
     ///
     /// \return Number of samples
     ///
+    /// \see getSamples
+    ///
     ////////////////////////////////////////////////////////////
-    std::size_t GetSamplesCount() const;
+    std::size_t getSampleCount() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the sample rate
+    /// \brief Get the sample rate of the sound
+    ///
+    /// The sample rate is the number of samples played per second.
+    /// The higher, the better the quality (for example, 44100
+    /// samples/s is CD quality).
     ///
-    /// \return Sound frequency (number of samples per second)
+    /// \return Sample rate (number of samples per second)
+    ///
+    /// \see getChannelCount, getDuration
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetSampleRate() const;
+    unsigned int getSampleRate() const;
 
     ////////////////////////////////////////////////////////////
-    /// Return the number of channels (1 = mono, 2 = stereo, ...)
+    /// \brief Get the number of channels used by the sound
+    ///
+    /// If the sound is mono then the number of channels will
+    /// be 1, 2 for stereo, etc.
     ///
     /// \return Number of channels
     ///
+    /// \see getSampleRate, getDuration
+    ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetChannelsCount() const;
+    unsigned int getChannelCount() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the sound duration
+    /// \brief Get the total duration of the sound
+    ///
+    /// \return Sound duration
     ///
-    /// \return Sound duration, in seconds
+    /// \see getSampleRate, getChannelCount
     ///
     ////////////////////////////////////////////////////////////
-    float GetDuration() const;
+    Time getDuration() const;
 
     ////////////////////////////////////////////////////////////
-    /// Assignment operator
+    /// \brief Overload of assignment operator
     ///
-    /// \param Other : Instance to assign
+    /// \param right Instance to assign
     ///
-    /// \return Reference to the sound buffer
+    /// \return Reference to self
     ///
     ////////////////////////////////////////////////////////////
-    SoundBuffer& operator =(const SoundBuffer& Other);
+    SoundBuffer& operator =(const SoundBuffer& right);
 
-private :
+private:
 
     friend class Sound;
 
     ////////////////////////////////////////////////////////////
-    /// Update the internal buffer with the audio samples
+    /// \brief Initialize the internal state after loading a new sound
+    ///
+    /// \param file Sound file providing access to the new loaded sound
+    ///
+    /// \return True on succesful initialization, false on failure
+    ///
+    ////////////////////////////////////////////////////////////
+    bool initialize(priv::SoundFile& file);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the internal buffer with the cached audio samples
     ///
-    /// \param ChannelsCount : Number of channels
-    /// \param SampleRate :    Sample rate
+    /// \param channelCount Number of channels
+    /// \param sampleRate   Sample rate (number of samples per second)
     ///
-    /// \return True on success
+    /// \return True on success, false if any error happened
     ///
     ////////////////////////////////////////////////////////////
-    bool Update(unsigned int ChannelsCount, unsigned int SampleRate);
+    bool update(unsigned int channelCount, unsigned int sampleRate);
 
     ////////////////////////////////////////////////////////////
-    /// Add a sound to the list of sounds that use this buffer
+    /// \brief Add a sound to the list of sounds that use this buffer
     ///
-    /// \param Instance : Sound object to attach
+    /// \param sound Sound instance to attach
     ///
     ////////////////////////////////////////////////////////////
-    void AttachSound(Sound* Instance) const;
+    void attachSound(Sound* sound) const;
 
     ////////////////////////////////////////////////////////////
-    /// Remove a sound from the list of sounds that use this buffer
+    /// \brief Remove a sound from the list of sounds that use this buffer
     ///
-    /// \param Instance : Sound object to detach
+    /// \param sound Sound instance to detach
     ///
     ////////////////////////////////////////////////////////////
-    void DetachSound(Sound* Instance) const;
+    void detachSound(Sound* sound) const;
 
     ////////////////////////////////////////////////////////////
     // Types
@@ -170,13 +279,81 @@ private :
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    unsigned int       myBuffer;   ///< OpenAL buffer identifier
-    std::vector<Int16> mySamples;  ///< Samples buffer
-    float              myDuration; ///< Sound duration, in seconds
-    mutable SoundList  mySounds;   ///< List of sounds that are using this buffer
+    unsigned int       m_buffer;   ///< OpenAL buffer identifier
+    std::vector<Int16> m_samples;  ///< Samples buffer
+    Time               m_duration; ///< Sound duration
+    mutable SoundList  m_sounds;   ///< List of sounds that are using this buffer
 };
 
 } // namespace sf
 
 
 #endif // SFML_SOUNDBUFFER_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::SoundBuffer
+/// \ingroup audio
+///
+/// A sound buffer holds the data of a sound, which is
+/// an array of audio samples. A sample is a 16 bits signed integer
+/// that defines the amplitude of the sound at a given time.
+/// The sound is then restituted by playing these samples at
+/// a high rate (for example, 44100 samples per second is the
+/// standard rate used for playing CDs). In short, audio samples
+/// are like texture pixels, and a sf::SoundBuffer is similar to
+/// a sf::Texture.
+///
+/// A sound buffer can be loaded from a file (see loadFromFile()
+/// for the complete list of supported formats), from memory, from
+/// a custom stream (see sf::InputStream) or directly from an array
+/// of samples. It can also be saved back to a file.
+///
+/// Sound buffers alone are not very useful: they hold the audio data
+/// but cannot be played. To do so, you need to use the sf::Sound class,
+/// which provides functions to play/pause/stop the sound as well as
+/// changing the way it is outputted (volume, pitch, 3D position, ...).
+/// This separation allows more flexibility and better performances:
+/// indeed a sf::SoundBuffer is a heavy resource, and any operation on it
+/// is slow (often too slow for real-time applications). On the other
+/// side, a sf::Sound is a lightweight object, which can use the audio data
+/// of a sound buffer and change the way it is played without actually
+/// modifying that data. Note that it is also possible to bind
+/// several sf::Sound instances to the same sf::SoundBuffer.
+///
+/// It is important to note that the sf::Sound instance doesn't
+/// copy the buffer that it uses, it only keeps a reference to it.
+/// Thus, a sf::SoundBuffer must not be destructed while it is
+/// used by a sf::Sound (i.e. never write a function that
+/// uses a local sf::SoundBuffer instance for loading a sound).
+///
+/// Usage example:
+/// \code
+/// // Declare a new sound buffer
+/// sf::SoundBuffer buffer;
+/// 
+/// // Load it from a file
+/// if (!buffer.loadFromFile("sound.wav"))
+/// {
+///     // error...
+/// }
+/// 
+/// // Create a sound source and bind it to the buffer
+/// sf::Sound sound1;
+/// sound1.setBuffer(buffer);
+/// 
+/// // Play the sound
+/// sound1.play();
+/// 
+/// // Create another sound source bound to the same buffer
+/// sf::Sound sound2;
+/// sound2.setBuffer(buffer);
+///
+/// // Play it with a higher pitch -- the first sound remains unchanged
+/// sound2.setPitch(2);
+/// sound2.play();
+/// \endcode
+///
+/// \see sf::Sound, sf::SoundBufferRecorder
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Audio/SoundBufferRecorder.hpp b/dependencies64/sfml/include/SFML/Audio/SoundBufferRecorder.hpp
new file mode 100644 (file)
index 0000000..cb174b0
--- /dev/null
@@ -0,0 +1,138 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOUNDBUFFERRECORDER_HPP
+#define SFML_SOUNDBUFFERRECORDER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Audio/Export.hpp>
+#include <SFML/Audio/SoundBuffer.hpp>
+#include <SFML/Audio/SoundRecorder.hpp>
+#include <vector>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Specialized SoundRecorder which stores the captured
+///        audio data into a sound buffer
+///
+////////////////////////////////////////////////////////////
+class SFML_AUDIO_API SoundBufferRecorder : public SoundRecorder
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the sound buffer containing the captured audio data
+    ///
+    /// The sound buffer is valid only after the capture has ended.
+    /// This function provides a read-only access to the internal
+    /// sound buffer, but it can be copied if you need to
+    /// make any modification to it.
+    ///
+    /// \return Read-only access to the sound buffer
+    ///
+    ////////////////////////////////////////////////////////////
+    const SoundBuffer& getBuffer() const;
+
+protected:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Start capturing audio data
+    ///
+    /// \return True to start the capture, or false to abort it
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool onStart();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Process a new chunk of recorded samples
+    ///
+    /// \param samples     Pointer to the new chunk of recorded samples
+    /// \param sampleCount Number of samples pointed by \a samples
+    ///
+    /// \return True to continue the capture, or false to stop it
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool onProcessSamples(const Int16* samples, std::size_t sampleCount);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Stop capturing audio data
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual void onStop();
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    std::vector<Int16> m_samples; ///< Temporary sample buffer to hold the recorded data
+    SoundBuffer        m_buffer;  ///< Sound buffer that will contain the recorded data
+};
+
+} // namespace sf
+
+#endif // SFML_SOUNDBUFFERRECORDER_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::SoundBufferRecorder
+/// \ingroup audio
+///
+/// sf::SoundBufferRecorder allows to access a recorded sound
+/// through a sf::SoundBuffer, so that it can be played, saved
+/// to a file, etc.
+///
+/// It has the same simple interface as its base class (start(), stop())
+/// and adds a function to retrieve the recorded sound buffer
+/// (getBuffer()).
+///
+/// As usual, don't forget to call the isAvailable() function
+/// before using this class (see sf::SoundRecorder for more details
+/// about this).
+///
+/// Usage example:
+/// \code
+/// if (sf::SoundBufferRecorder::isAvailable())
+/// {
+///     // Record some audio data
+///     sf::SoundBufferRecorder recorder;
+///     recorder.start();
+///     ...
+///     recorder.stop();
+///
+///     // Get the buffer containing the captured audio data
+///     const sf::SoundBuffer& buffer = recorder.getBuffer();
+///
+///     // Save it to a file (for example...)
+///     buffer.saveToFile("my_record.ogg");
+/// }
+/// \endcode
+///
+/// \see sf::SoundRecorder
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Audio/SoundRecorder.hpp b/dependencies64/sfml/include/SFML/Audio/SoundRecorder.hpp
new file mode 100644 (file)
index 0000000..733fd32
--- /dev/null
@@ -0,0 +1,363 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOUNDRECORDER_HPP
+#define SFML_SOUNDRECORDER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Audio/Export.hpp>
+#include <SFML/System/Thread.hpp>
+#include <SFML/System/Time.hpp>
+#include <vector>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Abstract base class for capturing sound data
+///
+////////////////////////////////////////////////////////////
+class SFML_AUDIO_API SoundRecorder
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~SoundRecorder();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Start the capture
+    ///
+    /// The \a sampleRate parameter defines the number of audio samples
+    /// captured per second. The higher, the better the quality
+    /// (for example, 44100 samples/sec is CD quality).
+    /// This function uses its own thread so that it doesn't block
+    /// the rest of the program while the capture runs.
+    /// Please note that only one capture can happen at the same time.
+    /// You can select which capture device will be used, by passing
+    /// the name to the setDevice() method. If none was selected
+    /// before, the default capture device will be used. You can get a
+    /// list of the names of all available capture devices by calling
+    /// getAvailableDevices().
+    ///
+    /// \param sampleRate Desired capture rate, in number of samples per second
+    ///
+    /// \return True, if start of capture was successful
+    ///
+    /// \see stop, getAvailableDevices
+    ///
+    ////////////////////////////////////////////////////////////
+    bool start(unsigned int sampleRate = 44100);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Stop the capture
+    ///
+    /// \see start
+    ///
+    ////////////////////////////////////////////////////////////
+    void stop();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the sample rate
+    ///
+    /// The sample rate defines the number of audio samples
+    /// captured per second. The higher, the better the quality
+    /// (for example, 44100 samples/sec is CD quality).
+    ///
+    /// \return Sample rate, in samples per second
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned int getSampleRate() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a list of the names of all available audio capture devices
+    ///
+    /// This function returns a vector of strings, containing
+    /// the names of all available audio capture devices.
+    ///
+    /// \return A vector of strings containing the names
+    ///
+    ////////////////////////////////////////////////////////////
+    static std::vector<std::string> getAvailableDevices();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the name of the default audio capture device
+    ///
+    /// This function returns the name of the default audio
+    /// capture device. If none is available, an empty string
+    /// is returned.
+    ///
+    /// \return The name of the default audio capture device
+    ///
+    ////////////////////////////////////////////////////////////
+    static std::string getDefaultDevice();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the audio capture device
+    ///
+    /// This function sets the audio capture device to the device
+    /// with the given \a name. It can be called on the fly (i.e:
+    /// while recording). If you do so while recording and
+    /// opening the device fails, it stops the recording.
+    ///
+    /// \param name The name of the audio capture device
+    ///
+    /// \return True, if it was able to set the requested device
+    ///
+    /// \see getAvailableDevices, getDefaultDevice
+    ///
+    ////////////////////////////////////////////////////////////
+    bool setDevice(const std::string& name);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the name of the current audio capture device
+    ///
+    /// \return The name of the current audio capture device
+    ///
+    ////////////////////////////////////////////////////////////
+    const std::string& getDevice() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if the system supports audio capture
+    ///
+    /// This function should always be called before using
+    /// the audio capture features. If it returns false, then
+    /// any attempt to use sf::SoundRecorder or one of its derived
+    /// classes will fail.
+    ///
+    /// \return True if audio capture is supported, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isAvailable();
+
+protected:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor is only meant to be called by derived classes.
+    ///
+    ////////////////////////////////////////////////////////////
+    SoundRecorder();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the processing interval
+    ///
+    /// The processing interval controls the period
+    /// between calls to the onProcessSamples function. You may
+    /// want to use a small interval if you want to process the
+    /// recorded data in real time, for example.
+    ///
+    /// Note: this is only a hint, the actual period may vary.
+    /// So don't rely on this parameter to implement precise timing.
+    ///
+    /// The default processing interval is 100 ms.
+    ///
+    /// \param interval Processing interval
+    ///
+    ////////////////////////////////////////////////////////////
+    void setProcessingInterval(sf::Time interval);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Start capturing audio data
+    ///
+    /// This virtual function may be overridden by a derived class
+    /// if something has to be done every time a new capture
+    /// starts. If not, this function can be ignored; the default
+    /// implementation does nothing.
+    ///
+    /// \return True to start the capture, or false to abort it
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool onStart();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Process a new chunk of recorded samples
+    ///
+    /// This virtual function is called every time a new chunk of
+    /// recorded data is available. The derived class can then do
+    /// whatever it wants with it (storing it, playing it, sending
+    /// it over the network, etc.).
+    ///
+    /// \param samples     Pointer to the new chunk of recorded samples
+    /// \param sampleCount Number of samples pointed by \a samples
+    ///
+    /// \return True to continue the capture, or false to stop it
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool onProcessSamples(const Int16* samples, std::size_t sampleCount) = 0;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Stop capturing audio data
+    ///
+    /// This virtual function may be overridden by a derived class
+    /// if something has to be done every time the capture
+    /// ends. If not, this function can be ignored; the default
+    /// implementation does nothing.
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual void onStop();
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Function called as the entry point of the thread
+    ///
+    /// This function starts the recording loop, and returns
+    /// only when the capture is stopped.
+    ///
+    ////////////////////////////////////////////////////////////
+    void record();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the new available audio samples and process them
+    ///
+    /// This function is called continuously during the
+    /// capture loop. It retrieves the captured samples and
+    /// forwards them to the derived class.
+    ///
+    ////////////////////////////////////////////////////////////
+    void processCapturedSamples();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Clean up the recorder's internal resources
+    ///
+    /// This function is called when the capture stops.
+    ///
+    ////////////////////////////////////////////////////////////
+    void cleanup();
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Thread             m_thread;             ///< Thread running the background recording task
+    std::vector<Int16> m_samples;            ///< Buffer to store captured samples
+    unsigned int       m_sampleRate;         ///< Sample rate
+    sf::Time           m_processingInterval; ///< Time period between calls to onProcessSamples
+    bool               m_isCapturing;        ///< Capturing state
+    std::string        m_deviceName;         ///< Name of the audio capture device
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOUNDRECORDER_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::SoundRecorder
+/// \ingroup audio
+///
+/// sf::SoundBuffer provides a simple interface to access
+/// the audio recording capabilities of the computer
+/// (the microphone). As an abstract base class, it only cares
+/// about capturing sound samples, the task of making something
+/// useful with them is left to the derived class. Note that
+/// SFML provides a built-in specialization for saving the
+/// captured data to a sound buffer (see sf::SoundBufferRecorder).
+///
+/// A derived class has only one virtual function to override:
+/// \li onProcessSamples provides the new chunks of audio samples while the capture happens
+///
+/// Moreover, two additional virtual functions can be overridden
+/// as well if necessary:
+/// \li onStart is called before the capture happens, to perform custom initializations
+/// \li onStop is called after the capture ends, to perform custom cleanup
+///
+/// A derived class can also control the frequency of the onProcessSamples
+/// calls, with the setProcessingInterval protected function. The default
+/// interval is chosen so that recording thread doesn't consume too much
+/// CPU, but it can be changed to a smaller value if you need to process
+/// the recorded data in real time, for example.
+///
+/// The audio capture feature may not be supported or activated
+/// on every platform, thus it is recommended to check its
+/// availability with the isAvailable() function. If it returns
+/// false, then any attempt to use an audio recorder will fail.
+///
+/// If you have multiple sound input devices connected to your
+/// computer (for example: microphone, external soundcard, webcam mic, ...)
+/// you can get a list of all available devices through the
+/// getAvailableDevices() function. You can then select a device
+/// by calling setDevice() with the appropriate device. Otherwise
+/// the default capturing device will be used.
+///
+/// It is important to note that the audio capture happens in a
+/// separate thread, so that it doesn't block the rest of the
+/// program. In particular, the onProcessSamples virtual function
+/// (but not onStart and not onStop) will be called
+/// from this separate thread. It is important to keep this in
+/// mind, because you may have to take care of synchronization
+/// issues if you share data between threads.
+///
+/// Usage example:
+/// \code
+/// class CustomRecorder : public sf::SoundRecorder
+/// {
+///     virtual bool onStart() // optional
+///     {
+///         // Initialize whatever has to be done before the capture starts
+///         ...
+///
+///         // Return true to start playing
+///         return true;
+///     }
+///
+///     virtual bool onProcessSamples(const Int16* samples, std::size_t sampleCount)
+///     {
+///         // Do something with the new chunk of samples (store them, send them, ...)
+///         ...
+///
+///         // Return true to continue playing
+///         return true;
+///     }
+///
+///     virtual void onStop() // optional
+///     {
+///         // Clean up whatever has to be done after the capture ends
+///         ...
+///     }
+/// }
+///
+/// // Usage
+/// if (CustomRecorder::isAvailable())
+/// {
+///     CustomRecorder recorder;
+///
+///     if (!recorder.start())
+///         return -1;
+///
+///     ...
+///     recorder.stop();
+/// }
+/// \endcode
+///
+/// \see sf::SoundBufferRecorder
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Audio/SoundSource.hpp b/dependencies64/sfml/include/SFML/Audio/SoundSource.hpp
new file mode 100644 (file)
index 0000000..f8ba48a
--- /dev/null
@@ -0,0 +1,286 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOUNDSOURCE_HPP
+#define SFML_SOUNDSOURCE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Audio/Export.hpp>
+#include <SFML/System/Vector3.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Base class defining a sound's properties
+///
+////////////////////////////////////////////////////////////
+class SFML_AUDIO_API SoundSource
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enumeration of the sound source states
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Status
+    {
+        Stopped, ///< Sound is not playing
+        Paused,  ///< Sound is paused
+        Playing  ///< Sound is playing
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Copy constructor
+    ///
+    /// \param copy Instance to copy
+    ///
+    ////////////////////////////////////////////////////////////
+    SoundSource(const SoundSource& copy);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~SoundSource();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the pitch of the sound
+    ///
+    /// The pitch represents the perceived fundamental frequency
+    /// of a sound; thus you can make a sound more acute or grave
+    /// by changing its pitch. A side effect of changing the pitch
+    /// is to modify the playing speed of the sound as well.
+    /// The default value for the pitch is 1.
+    ///
+    /// \param pitch New pitch to apply to the sound
+    ///
+    /// \see getPitch
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPitch(float pitch);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the volume of the sound
+    ///
+    /// The volume is a value between 0 (mute) and 100 (full volume).
+    /// The default value for the volume is 100.
+    ///
+    /// \param volume Volume of the sound
+    ///
+    /// \see getVolume
+    ///
+    ////////////////////////////////////////////////////////////
+    void setVolume(float volume);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the 3D position of the sound in the audio scene
+    ///
+    /// Only sounds with one channel (mono sounds) can be
+    /// spatialized.
+    /// The default position of a sound is (0, 0, 0).
+    ///
+    /// \param x X coordinate of the position of the sound in the scene
+    /// \param y Y coordinate of the position of the sound in the scene
+    /// \param z Z coordinate of the position of the sound in the scene
+    ///
+    /// \see getPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPosition(float x, float y, float z);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the 3D position of the sound in the audio scene
+    ///
+    /// Only sounds with one channel (mono sounds) can be
+    /// spatialized.
+    /// The default position of a sound is (0, 0, 0).
+    ///
+    /// \param position Position of the sound in the scene
+    ///
+    /// \see getPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPosition(const Vector3f& position);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Make the sound's position relative to the listener or absolute
+    ///
+    /// Making a sound relative to the listener will ensure that it will always
+    /// be played the same way regardless of the position of the listener.
+    /// This can be useful for non-spatialized sounds, sounds that are
+    /// produced by the listener, or sounds attached to it.
+    /// The default value is false (position is absolute).
+    ///
+    /// \param relative True to set the position relative, false to set it absolute
+    ///
+    /// \see isRelativeToListener
+    ///
+    ////////////////////////////////////////////////////////////
+    void setRelativeToListener(bool relative);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the minimum distance of the sound
+    ///
+    /// The "minimum distance" of a sound is the maximum
+    /// distance at which it is heard at its maximum volume. Further
+    /// than the minimum distance, it will start to fade out according
+    /// to its attenuation factor. A value of 0 ("inside the head
+    /// of the listener") is an invalid value and is forbidden.
+    /// The default value of the minimum distance is 1.
+    ///
+    /// \param distance New minimum distance of the sound
+    ///
+    /// \see getMinDistance, setAttenuation
+    ///
+    ////////////////////////////////////////////////////////////
+    void setMinDistance(float distance);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the attenuation factor of the sound
+    ///
+    /// The attenuation is a multiplicative factor which makes
+    /// the sound more or less loud according to its distance
+    /// from the listener. An attenuation of 0 will produce a
+    /// non-attenuated sound, i.e. its volume will always be the same
+    /// whether it is heard from near or from far. On the other hand,
+    /// an attenuation value such as 100 will make the sound fade out
+    /// very quickly as it gets further from the listener.
+    /// The default value of the attenuation is 1.
+    ///
+    /// \param attenuation New attenuation factor of the sound
+    ///
+    /// \see getAttenuation, setMinDistance
+    ///
+    ////////////////////////////////////////////////////////////
+    void setAttenuation(float attenuation);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the pitch of the sound
+    ///
+    /// \return Pitch of the sound
+    ///
+    /// \see setPitch
+    ///
+    ////////////////////////////////////////////////////////////
+    float getPitch() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the volume of the sound
+    ///
+    /// \return Volume of the sound, in the range [0, 100]
+    ///
+    /// \see setVolume
+    ///
+    ////////////////////////////////////////////////////////////
+    float getVolume() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the 3D position of the sound in the audio scene
+    ///
+    /// \return Position of the sound
+    ///
+    /// \see setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector3f getPosition() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether the sound's position is relative to the
+    ///        listener or is absolute
+    ///
+    /// \return True if the position is relative, false if it's absolute
+    ///
+    /// \see setRelativeToListener
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isRelativeToListener() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the minimum distance of the sound
+    ///
+    /// \return Minimum distance of the sound
+    ///
+    /// \see setMinDistance, getAttenuation
+    ///
+    ////////////////////////////////////////////////////////////
+    float getMinDistance() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the attenuation factor of the sound
+    ///
+    /// \return Attenuation factor of the sound
+    ///
+    /// \see setAttenuation, getMinDistance
+    ///
+    ////////////////////////////////////////////////////////////
+    float getAttenuation() const;
+
+protected:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor is meant to be called by derived classes only.
+    ///
+    ////////////////////////////////////////////////////////////
+    SoundSource();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current status of the sound (stopped, paused, playing)
+    ///
+    /// \return Current status of the sound
+    ///
+    ////////////////////////////////////////////////////////////
+    Status getStatus() const;
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    unsigned int m_source; ///< OpenAL source identifier
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOUNDSOURCE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::SoundSource
+/// \ingroup audio
+///
+/// sf::SoundSource is not meant to be used directly, it
+/// only serves as a common base for all audio objects
+/// that can live in the audio environment.
+///
+/// It defines several properties for the sound: pitch,
+/// volume, position, attenuation, etc. All of them can be
+/// changed at any time with no impact on performances.
+///
+/// \see sf::Sound, sf::SoundStream
+///
+////////////////////////////////////////////////////////////
index 1f0f8ba2cd220b675664487fa868fb1afaed05f0..e79d879b64a4127a0e9502d1e86d587299d21ed8 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Audio/Sound.hpp>
+#include <SFML/Audio/Export.hpp>
+#include <SFML/Audio/SoundSource.hpp>
 #include <SFML/System/Thread.hpp>
+#include <SFML/System/Time.hpp>
+#include <SFML/System/Mutex.hpp>
 #include <cstdlib>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// SoundStream is a streamed sound, ie samples are acquired
-/// while the sound is playing. Use it for big sounds that would
-/// require hundreds of MB in memory (see Music),
-/// or for streaming sound from the network
+/// \brief Abstract base class for streamed audio sources
+///
 ////////////////////////////////////////////////////////////
-class SFML_API SoundStream : private Thread, private Sound
+class SFML_AUDIO_API SoundStream : public SoundSource
 {
-public :
-
-    using Sound::Status;
-    using Sound::Stopped;
-    using Sound::Paused;
-    using Sound::Playing;
-    using Sound::Pause;
-    using Sound::SetPitch;
-    using Sound::SetVolume;
-    using Sound::SetPosition;
-    using Sound::SetRelativeToListener;
-    using Sound::SetMinDistance;
-    using Sound::SetAttenuation;
-    using Sound::GetPitch;
-    using Sound::GetVolume;
-    using Sound::GetPosition;
-    using Sound::IsRelativeToListener;
-    using Sound::GetMinDistance;
-    using Sound::GetAttenuation;
-
-    ////////////////////////////////////////////////////////////
-    /// Structure defining a chunk of audio data to stream
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Structure defining a chunk of audio data to stream
+    ///
     ////////////////////////////////////////////////////////////
     struct Chunk
     {
-        const Int16* Samples;   ///< Pointer to the audio samples
-        std::size_t  NbSamples; ///< Number of samples pointed by Samples
+        const Int16* samples;     ///< Pointer to the audio samples
+        std::size_t  sampleCount; ///< Number of samples pointed by Samples
     };
 
     ////////////////////////////////////////////////////////////
-    /// Virtual destructor
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
     virtual ~SoundStream();
 
     ////////////////////////////////////////////////////////////
-    /// Start playing the audio stream
+    /// \brief Start or resume playing the audio stream
+    ///
+    /// This function starts the stream if it was stopped, resumes
+    /// it if it was paused, and restarts it from the beginning if
+    /// it was already playing.
+    /// This function uses its own thread so that it doesn't block
+    /// the rest of the program while the stream is played.
+    ///
+    /// \see pause, stop
     ///
     ////////////////////////////////////////////////////////////
-    void Play();
+    void play();
 
     ////////////////////////////////////////////////////////////
-    /// Stop playing the audio stream
+    /// \brief Pause the audio stream
+    ///
+    /// This function pauses the stream if it was playing,
+    /// otherwise (stream already paused or stopped) it has no effect.
+    ///
+    /// \see play, stop
     ///
     ////////////////////////////////////////////////////////////
-    void Stop();
+    void pause();
 
     ////////////////////////////////////////////////////////////
-    /// Return the number of channels (1 = mono, 2 = stereo)
+    /// \brief Stop playing the audio stream
     ///
-    /// \return Number of channels
+    /// This function stops the stream if it was playing or paused,
+    /// and does nothing if it was already stopped.
+    /// It also resets the playing position (unlike pause()).
+    ///
+    /// \see play, pause
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetChannelsCount() const;
+    void stop();
 
     ////////////////////////////////////////////////////////////
-    /// Get the stream sample rate
+    /// \brief Return the number of channels of the stream
     ///
-    /// \return Stream frequency (number of samples per second)
+    /// 1 channel means a mono sound, 2 means stereo, etc.
+    ///
+    /// \return Number of channels
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetSampleRate() const;
+    unsigned int getChannelCount() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the status of the stream (stopped, paused, playing)
+    /// \brief Get the stream sample rate of the stream
+    ///
+    /// The sample rate is the number of audio samples played per
+    /// second. The higher, the better the quality.
     ///
-    /// \return Current status of the sound
+    /// \return Sample rate, in number of samples per second
     ///
     ////////////////////////////////////////////////////////////
-    Status GetStatus() const;
+    unsigned int getSampleRate() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the current playing position of the stream
+    /// \brief Get the current status of the stream (stopped, paused, playing)
     ///
-    /// \return Current playing position, expressed in seconds
+    /// \return Current status
     ///
     ////////////////////////////////////////////////////////////
-    float GetPlayingOffset() const;
+    Status getStatus() const;
 
     ////////////////////////////////////////////////////////////
-    /// Set the stream loop state.
-    /// This parameter is disabled by default
+    /// \brief Change the current playing position of the stream
     ///
-    /// \param Loop : True to play in loop, false to play once
+    /// The playing position can be changed when the stream is
+    /// either paused or playing. Changing the playing position
+    /// when the stream is stopped has no effect, since playing
+    /// the stream would reset its position.
+    ///
+    /// \param timeOffset New playing position, from the beginning of the stream
+    ///
+    /// \see getPlayingOffset
     ///
     ////////////////////////////////////////////////////////////
-    void SetLoop(bool Loop);
+    void setPlayingOffset(Time timeOffset);
 
     ////////////////////////////////////////////////////////////
-    /// Tell whether or not the stream is looping
+    /// \brief Get the current playing position of the stream
+    ///
+    /// \return Current playing position, from the beginning of the stream
     ///
-    /// \return True if the music is looping, false otherwise
+    /// \see setPlayingOffset
     ///
     ////////////////////////////////////////////////////////////
-    bool GetLoop() const;
-
-protected :
+    Time getPlayingOffset() const;
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Set whether or not the stream should loop after reaching the end
+    ///
+    /// If set, the stream will restart from beginning after
+    /// reaching the end and so on, until it is stopped or
+    /// setLoop(false) is called.
+    /// The default looping state for streams is false.
+    ///
+    /// \param loop True to play in loop, false to play once
+    ///
+    /// \see getLoop
     ///
     ////////////////////////////////////////////////////////////
-    SoundStream();
+    void setLoop(bool loop);
 
     ////////////////////////////////////////////////////////////
-    /// Set the audio stream parameters, you must call it before Play()
+    /// \brief Tell whether or not the stream is in loop mode
+    ///
+    /// \return True if the stream is looping, false otherwise
     ///
-    /// \param ChannelsCount : Number of channels
-    /// \param SampleRate :    Sample rate
+    /// \see setLoop
     ///
     ////////////////////////////////////////////////////////////
-    void Initialize(unsigned int ChannelsCount, unsigned int SampleRate);
+    bool getLoop() const;
 
-private :
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// /see Thread::Run
+    /// \brief Default constructor
+    ///
+    /// This constructor is only meant to be called by derived classes.
     ///
     ////////////////////////////////////////////////////////////
-    virtual void Run();
+    SoundStream();
 
     ////////////////////////////////////////////////////////////
-    /// Called when the sound restarts
+    /// \brief Define the audio stream parameters
     ///
-    /// \return If false is returned, the playback is aborted
+    /// This function must be called by derived classes as soon
+    /// as they know the audio settings of the stream to play.
+    /// Any attempt to manipulate the stream (play(), ...) before
+    /// calling this function will fail.
+    /// It can be called multiple times if the settings of the
+    /// audio stream change, but only when the stream is stopped.
+    ///
+    /// \param channelCount Number of channels of the stream
+    /// \param sampleRate   Sample rate, in samples per second
     ///
     ////////////////////////////////////////////////////////////
-    virtual bool OnStart();
+    void initialize(unsigned int channelCount, unsigned int sampleRate);
 
     ////////////////////////////////////////////////////////////
-    /// Called each time new audio data is needed to feed the stream
+    /// \brief Request a new chunk of audio samples from the stream source
+    ///
+    /// This function must be overridden by derived classes to provide
+    /// the audio samples to play. It is called continuously by the
+    /// streaming loop, in a separate thread.
+    /// The source can choose to stop the streaming loop at any time, by
+    /// returning false to the caller.
+    /// If you return true (i.e. continue streaming) it is important that
+    /// the returned array of samples is not empty; this would stop the stream
+    /// due to an internal limitation.
     ///
-    /// \param Data : New chunk of data to stream
+    /// \param data Chunk of data to fill
     ///
     /// \return True to continue playback, false to stop
     ///
     ////////////////////////////////////////////////////////////
-    virtual bool OnGetData(Chunk& Data) = 0;
+    virtual bool onGetData(Chunk& data) = 0;
 
     ////////////////////////////////////////////////////////////
-    /// Fill a new buffer with audio data, and push it to the
-    /// playing queue
+    /// \brief Change the current playing position in the stream source
     ///
-    /// \param Buffer : Number of the buffer to fill (in [0, BuffersCount])
+    /// This function must be overridden by derived classes to
+    /// allow random seeking into the stream source.
     ///
-    /// \return True if the derived class has requested to stop
+    /// \param timeOffset New playing position, relative to the beginning of the stream
     ///
     ////////////////////////////////////////////////////////////
-    bool FillAndPushBuffer(unsigned int BufferNum);
+    virtual void onSeek(Time timeOffset) = 0;
+
+private:
 
     ////////////////////////////////////////////////////////////
-    /// Fill the buffers queue with all available buffers
+    /// \brief Function called as the entry point of the thread
     ///
-    /// \return True if the derived class has requested to stop
+    /// This function starts the streaming loop, and returns
+    /// only when the sound is stopped.
     ///
     ////////////////////////////////////////////////////////////
-    bool FillQueue();
+    void streamData();
 
     ////////////////////////////////////////////////////////////
-    /// Clear the queue of any remaining buffers
+    /// \brief Fill a new buffer with audio samples, and append
+    ///        it to the playing queue
+    ///
+    /// This function is called as soon as a buffer has been fully
+    /// consumed; it fills it again and inserts it back into the
+    /// playing queue.
+    ///
+    /// \param bufferNum Number of the buffer to fill (in [0, BufferCount])
+    ///
+    /// \return True if the stream source has requested to stop, false otherwise
     ///
     ////////////////////////////////////////////////////////////
-    void ClearQueue();
+    bool fillAndPushBuffer(unsigned int bufferNum);
 
-    enum {BuffersCount = 3};
+    ////////////////////////////////////////////////////////////
+    /// \brief Fill the audio buffers and put them all into the playing queue
+    ///
+    /// This function is called when playing starts and the
+    /// playing queue is empty.
+    ///
+    /// \return True if the derived class has requested to stop, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    bool fillQueue();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Clear all the audio buffers and empty the playing queue
+    ///
+    /// This function is called when the stream is stopped.
+    ///
+    ////////////////////////////////////////////////////////////
+    void clearQueue();
+
+    enum
+    {
+        BufferCount = 3 ///< Number of audio buffers used by the streaming loop
+    };
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    bool          myIsStreaming;              ///< Streaming state (true = playing, false = stopped)
-    unsigned int  myBuffers[BuffersCount];    ///< Sound buffers used to store temporary audio data
-    unsigned int  myChannelsCount;            ///< Number of channels (1 = mono, 2 = stereo, ...)
-    unsigned int  mySampleRate;               ///< Frequency (samples / second)
-    unsigned long myFormat;                   ///< Format of the internal sound buffers
-    bool          myLoop;                     ///< Loop flag (true to loop, false to play once)
-    unsigned int  mySamplesProcessed;         ///< Number of buffers processed since beginning of the stream
-    bool          myEndBuffers[BuffersCount]; ///< Each buffer is marked as "end buffer" or not, for proper duration calculation
+    Thread        m_thread;                  ///< Thread running the background tasks
+    mutable Mutex m_threadMutex;             ///< Thread mutex
+    Status        m_threadStartState;        ///< State the thread starts in (Playing, Paused, Stopped)
+    bool          m_isStreaming;             ///< Streaming state (true = playing, false = stopped)
+    unsigned int  m_buffers[BufferCount];    ///< Sound buffers used to store temporary audio data
+    unsigned int  m_channelCount;            ///< Number of channels (1 = mono, 2 = stereo, ...)
+    unsigned int  m_sampleRate;              ///< Frequency (samples / second)
+    Uint32        m_format;                  ///< Format of the internal sound buffers
+    bool          m_loop;                    ///< Loop flag (true to loop, false to play once)
+    Uint64        m_samplesProcessed;        ///< Number of buffers processed since beginning of the stream
+    bool          m_endBuffers[BufferCount]; ///< Each buffer is marked as "end buffer" or not, for proper duration calculation
 };
 
 } // namespace sf
 
 
 #endif // SFML_SOUNDSTREAM_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::SoundStream
+/// \ingroup audio
+///
+/// Unlike audio buffers (see sf::SoundBuffer), audio streams
+/// are never completely loaded in memory. Instead, the audio
+/// data is acquired continuously while the stream is playing.
+/// This behavior allows to play a sound with no loading delay,
+/// and keeps the memory consumption very low.
+///
+/// Sound sources that need to be streamed are usually big files
+/// (compressed audio musics that would eat hundreds of MB in memory)
+/// or files that would take a lot of time to be received
+/// (sounds played over the network).
+///
+/// sf::SoundStream is a base class that doesn't care about the
+/// stream source, which is left to the derived class. SFML provides
+/// a built-in specialization for big files (see sf::Music).
+/// No network stream source is provided, but you can write your own
+/// by combining this class with the network module.
+///
+/// A derived class has to override two virtual functions:
+/// \li onGetData fills a new chunk of audio data to be played
+/// \li onSeek changes the current playing position in the source
+///
+/// It is important to note that each SoundStream is played in its
+/// own separate thread, so that the streaming loop doesn't block the
+/// rest of the program. In particular, the OnGetData and OnSeek
+/// virtual functions may sometimes be called from this separate thread.
+/// It is important to keep this in mind, because you may have to take
+/// care of synchronization issues if you share data between threads.
+///
+/// Usage example:
+/// \code
+/// class CustomStream : public sf::SoundStream
+/// {
+/// public:
+///
+///     bool open(const std::string& location)
+///     {
+///         // Open the source and get audio settings
+///         ...
+///         unsigned int channelCount = ...;
+///         unsigned int sampleRate = ...;
+///
+///         // Initialize the stream -- important!
+///         initialize(channelCount, sampleRate);
+///     }
+///
+/// private:
+///
+///     virtual bool onGetData(Chunk& data)
+///     {
+///         // Fill the chunk with audio data from the stream source
+///         // (note: must not be empty if you want to continue playing)
+///         data.samples = ...;
+///         data.sampleCount = ...;
+///
+///         // Return true to continue playing
+///         return true;
+///     }
+///
+///     virtual void onSeek(Uint32 timeOffset)
+///     {
+///         // Change the current position in the stream source
+///         ...
+///     }
+/// }
+///
+/// // Usage
+/// CustomStream stream;
+/// stream.open("path/to/stream");
+/// stream.play();
+/// \endcode
+///
+/// \see sf::Music
+///
+////////////////////////////////////////////////////////////
index 63ff46c4214825893700a433e02de97447c55937..a5ad154b6c29136032b936cd09f942d0c5360b89 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 #ifndef SFML_CONFIG_HPP
 #define SFML_CONFIG_HPP
 
+
+////////////////////////////////////////////////////////////
+// Define the SFML version
+////////////////////////////////////////////////////////////
+#define SFML_VERSION_MAJOR 2
+#define SFML_VERSION_MINOR 2
+#define SFML_VERSION_PATCH 0
+
+
 ////////////////////////////////////////////////////////////
 // Identify the operating system
+// see http://nadeausoftware.com/articles/2012/01/c_c_tip_how_use_compiler_predefined_macros_detect_operating_system
 ////////////////////////////////////////////////////////////
-#if defined(_WIN32) || defined(__WIN32__)
+#if defined(_WIN32)
 
     // Windows
     #define SFML_SYSTEM_WINDOWS
-    #ifndef WIN32_LEAN_AND_MEAN
-        #define WIN32_LEAN_AND_MEAN
-    #endif
     #ifndef NOMINMAX
         #define NOMINMAX
     #endif
 
-#elif defined(linux) || defined(__linux)
+#elif defined(__APPLE__) && defined(__MACH__)
+
+    // Apple platform, see which one it is
+    #include "TargetConditionals.h"
+
+    #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+
+        // iOS
+        #define SFML_SYSTEM_IOS
+
+    #elif TARGET_OS_MAC
+
+        // MacOS
+        #define SFML_SYSTEM_MACOS
+
+    #else
+
+        // Unsupported Apple system
+        #error This Apple operating system is not supported by SFML library
+
+    #endif
+
+#elif defined(__unix__)
+
+    // UNIX system, see which one it is
+    #if defined(__ANDROID__)
 
-    // Linux
-    #define SFML_SYSTEM_LINUX
+        // Android
+        #define SFML_SYSTEM_ANDROID
 
-#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)
+    #elif defined(__linux__)
 
-    // MacOS
-    #define SFML_SYSTEM_MACOS
+         // Linux
+        #define SFML_SYSTEM_LINUX
 
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
+    #elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
 
-    // FreeBSD
-    #define SFML_SYSTEM_FREEBSD
+        // FreeBSD
+        #define SFML_SYSTEM_FREEBSD
+
+    #else
+
+        // Unsupported UNIX system
+        #error This UNIX operating system is not supported by SFML library
+
+    #endif
 
 #else
 
 
 
 ////////////////////////////////////////////////////////////
-// Define portable import / export macros
+// Define helpers to create portable import / export macros for each module
 ////////////////////////////////////////////////////////////
-#if defined(SFML_SYSTEM_WINDOWS)
+#if !defined(SFML_STATIC)
 
-    #ifdef SFML_DYNAMIC
+    #if defined(SFML_SYSTEM_WINDOWS)
 
-        // Windows platforms
-        #ifdef SFML_EXPORTS
+        // Windows compilers need specific (and different) keywords for export and import
+        #define SFML_API_EXPORT __declspec(dllexport)
+        #define SFML_API_IMPORT __declspec(dllimport)
 
-            // From DLL side, we must export
-            #define SFML_API __declspec(dllexport)
-
-        #else
+        // For Visual C++ compilers, we also need to turn off this annoying C4251 warning
+        #ifdef _MSC_VER
 
-            // From client application side, we must import
-            #define SFML_API __declspec(dllimport)
+            #pragma warning(disable: 4251)
 
         #endif
 
-        // For Visual C++ compilers, we also need to turn off this annoying C4251 warning.
-        // You can read lots ot different things about it, but the point is the code will
-        // just work fine, and so the simplest way to get rid of this warning is to disable it
-        #ifdef _MSC_VER
+    #else // Linux, FreeBSD, Mac OS X
 
-            #pragma warning(disable : 4251)
+        #if __GNUC__ >= 4
 
-        #endif
+            // GCC 4 has special keywords for showing/hidding symbols,
+            // the same keyword is used for both importing and exporting
+            #define SFML_API_EXPORT __attribute__ ((__visibility__ ("default")))
+            #define SFML_API_IMPORT __attribute__ ((__visibility__ ("default")))
 
-    #else
+        #else
 
-        // No specific directive needed for static build
-        #define SFML_API
+            // GCC < 4 has no mechanism to explicitely hide symbols, everything's exported
+            #define SFML_API_EXPORT
+            #define SFML_API_IMPORT
+
+        #endif
 
     #endif
 
 #else
 
-    // Other platforms don't need to define anything
-    #define SFML_API
+    // Static build doesn't need import/export macros
+    #define SFML_API_EXPORT
+    #define SFML_API_IMPORT
 
 #endif
 
 ////////////////////////////////////////////////////////////
 // Define portable fixed-size types
 ////////////////////////////////////////////////////////////
-#include <climits>
-
 namespace sf
 {
+    // All "common" platforms use the same size for char, short and int
+    // (basically there are 3 types for 3 sizes, so no other match is possible),
+    // we can use them without doing any kind of check
+
     // 8 bits integer types
-    #if UCHAR_MAX == 0xFF
-        typedef signed   char Int8;
-        typedef unsigned char Uint8;
-    #else
-        #error No 8 bits integer type for this platform
-    #endif
+    typedef signed   char Int8;
+    typedef unsigned char Uint8;
 
     // 16 bits integer types
-    #if USHRT_MAX == 0xFFFF
-        typedef signed   short Int16;
-        typedef unsigned short Uint16;
-    #elif UINT_MAX == 0xFFFF
-        typedef signed   int Int16;
-        typedef unsigned int Uint16;
-    #elif ULONG_MAX == 0xFFFF
-        typedef signed   long Int16;
-        typedef unsigned long Uint16;
-    #else
-        #error No 16 bits integer type for this platform
-    #endif
+    typedef signed   short Int16;
+    typedef unsigned short Uint16;
 
     // 32 bits integer types
-    #if USHRT_MAX == 0xFFFFFFFF
-        typedef signed   short Int32;
-        typedef unsigned short Uint32;
-    #elif UINT_MAX == 0xFFFFFFFF
-        typedef signed   int Int32;
-        typedef unsigned int Uint32;
-    #elif ULONG_MAX == 0xFFFFFFFF
-        typedef signed   long Int32;
-        typedef unsigned long Uint32;
+    typedef signed   int Int32;
+    typedef unsigned int Uint32;
+
+    // 64 bits integer types
+    #if defined(_MSC_VER)
+        typedef signed   __int64 Int64;
+        typedef unsigned __int64 Uint64;
     #else
-        #error No 32 bits integer type for this platform
+        typedef signed   long long Int64;
+        typedef unsigned long long Uint64;
     #endif
 
 } // namespace sf
index 0f7b3652bd263340a4bd6205a97b8125bbf83681..ac5231c6d85025f2ecd56ba7582b579b495b6c06 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 
 #include <SFML/Window.hpp>
+#include <SFML/Graphics/BlendMode.hpp>
 #include <SFML/Graphics/Color.hpp>
 #include <SFML/Graphics/Font.hpp>
 #include <SFML/Graphics/Glyph.hpp>
 #include <SFML/Graphics/Image.hpp>
-#include <SFML/Graphics/PostFX.hpp>
+#include <SFML/Graphics/RenderStates.hpp>
+#include <SFML/Graphics/RenderTexture.hpp>
 #include <SFML/Graphics/RenderWindow.hpp>
+#include <SFML/Graphics/Shader.hpp>
 #include <SFML/Graphics/Shape.hpp>
+#include <SFML/Graphics/CircleShape.hpp>
+#include <SFML/Graphics/RectangleShape.hpp>
+#include <SFML/Graphics/ConvexShape.hpp>
 #include <SFML/Graphics/Sprite.hpp>
-#include <SFML/Graphics/String.hpp>
+#include <SFML/Graphics/Text.hpp>
+#include <SFML/Graphics/Texture.hpp>
+#include <SFML/Graphics/Transform.hpp>
+#include <SFML/Graphics/Vertex.hpp>
+#include <SFML/Graphics/VertexArray.hpp>
 #include <SFML/Graphics/View.hpp>
 
 
 #endif // SFML_GRAPHICS_HPP
+
+////////////////////////////////////////////////////////////
+/// \defgroup graphics Graphics module
+///
+/// 2D graphics module: sprites, text, shapes, ...
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/BlendMode.hpp b/dependencies64/sfml/include/SFML/Graphics/BlendMode.hpp
new file mode 100644 (file)
index 0000000..412286d
--- /dev/null
@@ -0,0 +1,214 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_BLENDMODE_HPP
+#define SFML_BLENDMODE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+
+
+namespace sf
+{
+
+////////////////////////////////////////////////////////////
+/// \brief Blending modes for drawing
+///
+////////////////////////////////////////////////////////////
+struct SFML_GRAPHICS_API BlendMode
+{
+    ////////////////////////////////////////////////////////
+    /// \brief Enumeration of the blending factors
+    ///
+    /// The factors are mapped directly to their OpenGL equivalents,
+    /// specified by glBlendFunc() or glBlendFuncSeparate().
+    ////////////////////////////////////////////////////////
+    enum Factor
+    {
+        Zero,             ///< (0, 0, 0, 0)
+        One,              ///< (1, 1, 1, 1)
+        SrcColor,         ///< (src.r, src.g, src.b, src.a)
+        OneMinusSrcColor, ///< (1, 1, 1, 1) - (src.r, src.g, src.b, src.a)
+        DstColor,         ///< (dst.r, dst.g, dst.b, dst.a)
+        OneMinusDstColor, ///< (1, 1, 1, 1) - (dst.r, dst.g, dst.b, dst.a)
+        SrcAlpha,         ///< (src.a, src.a, src.a, src.a)
+        OneMinusSrcAlpha, ///< (1, 1, 1, 1) - (src.a, src.a, src.a, src.a)
+        DstAlpha,         ///< (dst.a, dst.a, dst.a, dst.a)
+        OneMinusDstAlpha  ///< (1, 1, 1, 1) - (dst.a, dst.a, dst.a, dst.a)
+    };
+
+    ////////////////////////////////////////////////////////
+    /// \brief Enumeration of the blending equations
+    ///
+    /// The equations are mapped directly to their OpenGL equivalents,
+    /// specified by glBlendEquation() or glBlendEquationSeparate().
+    ////////////////////////////////////////////////////////
+    enum Equation
+    {
+        Add,     ///< Pixel = Src * SrcFactor + Dst * DstFactor
+        Subtract ///< Pixel = Src * SrcFactor - Dst * DstFactor
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Constructs a blending mode that does alpha blending.
+    ///
+    ////////////////////////////////////////////////////////////
+    BlendMode();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the blend mode given the factors and equation.
+    ///
+    /// This constructor uses the same factors and equation for both
+    /// color and alpha components. It also defaults to the Add equation.
+    ///
+    /// \param sourceFactor      Specifies how to compute the source factor for the color and alpha channels.
+    /// \param destinationFactor Specifies how to compute the destination factor for the color and alpha channels.
+    /// \param blendEquation     Specifies how to combine the source and destination colors and alpha.
+    ///
+    ////////////////////////////////////////////////////////////
+    BlendMode(Factor sourceFactor, Factor destinationFactor, Equation blendEquation = Add);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the blend mode given the factors and equation.
+    ///
+    /// \param colorSourceFactor      Specifies how to compute the source factor for the color channels.
+    /// \param colorDestinationFactor Specifies how to compute the destination factor for the color channels.
+    /// \param colorBlendEquation     Specifies how to combine the source and destination colors.
+    /// \param alphaSourceFactor      Specifies how to compute the source factor.
+    /// \param alphaDestinationFactor Specifies how to compute the destination factor.
+    /// \param alphaBlendEquation     Specifies how to combine the source and destination alphas.
+    ///
+    ////////////////////////////////////////////////////////////
+    BlendMode(Factor colorSourceFactor, Factor colorDestinationFactor,
+              Equation colorBlendEquation, Factor alphaSourceFactor,
+              Factor alphaDestinationFactor, Equation alphaBlendEquation);
+
+    ////////////////////////////////////////////////////////////
+    // Member Data
+    ////////////////////////////////////////////////////////////
+    Factor   colorSrcFactor; ///< Source blending factor for the color channels
+    Factor   colorDstFactor; ///< Destination blending factor for the color channels
+    Equation colorEquation;  ///< Blending equation for the color channels
+    Factor   alphaSrcFactor; ///< Source blending factor for the alpha channel
+    Factor   alphaDstFactor; ///< Destination blending factor for the alpha channel
+    Equation alphaEquation;  ///< Blending equation for the alpha channel
+};
+
+////////////////////////////////////////////////////////////
+/// \relates BlendMode
+/// \brief Overload of the == operator
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return True if blending modes are equal, false if they are different
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API bool operator ==(const BlendMode& left, const BlendMode& right);
+
+////////////////////////////////////////////////////////////
+/// \relates BlendMode
+/// \brief Overload of the != operator
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return True if blending modes are different, false if they are equal
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API bool operator !=(const BlendMode& left, const BlendMode& right);
+
+////////////////////////////////////////////////////////////
+// Commonly used blending modes
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API extern const BlendMode BlendAlpha;    ///< Blend source and dest according to dest alpha 
+SFML_GRAPHICS_API extern const BlendMode BlendAdd;      ///< Add source to dest
+SFML_GRAPHICS_API extern const BlendMode BlendMultiply; ///< Multiply source and dest
+SFML_GRAPHICS_API extern const BlendMode BlendNone;     ///< Overwrite dest with source
+
+} // namespace sf
+
+
+#endif // SFML_BLENDMODE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::BlendMode
+/// \ingroup graphics
+///
+/// sf::BlendMode is a class that represents a blend mode. A blend
+/// mode determines how the colors of an object you draw are
+/// mixed with the colors that are already in the buffer.
+/// 
+/// The class is composed of 6 components, each of which has its
+/// own public member variable:
+/// \li %Color Source Factor (@ref colorSrcFactor)
+/// \li %Color Destination Factor (@ref colorDstFactor)
+/// \li %Color Blend Equation (@ref colorEquation)
+/// \li Alpha Source Factor (@ref alphaSrcFactor)
+/// \li Alpha Destination Factor (@ref alphaDstFactor)
+/// \li Alpha Blend Equation (@ref alphaEquation)
+/// 
+/// The source factor specifies how the pixel you are drawing contributes
+/// to the final color. The destination factor specifies how the pixel
+/// already drawn in the buffer contributes to the final color.
+///
+/// The color channels RGB (red, green, blue; simply referred to as
+/// color) and A (alpha; the transparency) can be treated separately. This
+/// separation can be useful for specific blend modes, but most often you
+/// won't need it and will simply treat the color as a single unit.
+///
+/// The blend factors and equations correspond to their OpenGL equivalents.
+/// In general, the color of the resulting pixel is calculated according
+/// to the following formula (\a src is the color of the source pixel, \a dst
+/// the color of the destination pixel, the other variables correspond to the
+/// public members, with the equations being + or - operators):
+/// \code
+/// dst.rgb = colorSrcFactor * src.rgb (colorEquation) colorDstFactor * dst.rgb
+/// dst.a   = alphaSrcFactor * src.a   (alphaEquation) alphaDstFactor * dst.a
+/// \endcode
+/// All factors and colors are represented as floating point numbers between
+/// 0 and 1. Where necessary, the result is clamped to fit in that range.
+///
+/// The most common blending modes are defined as constants
+/// in the sf namespace:
+///
+/// \code
+/// sf::BlendMode alphaBlending          = sf::BlendAlpha;
+/// sf::BlendMode additiveBlending       = sf::BlendAdd;
+/// sf::BlendMode multiplicativeBlending = sf::BlendMultipy;
+/// sf::BlendMode noBlending             = sf::BlendNone;
+/// \endcode
+///
+/// In SFML, a blend mode can be specified every time you draw a sf::Drawable
+/// object to a render target. It is part of the sf::RenderStates compound
+/// that is passed to the member function sf::RenderTarget::draw().
+///
+/// \see sf::RenderStates, sf::RenderTarget
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/CircleShape.hpp b/dependencies64/sfml/include/SFML/Graphics/CircleShape.hpp
new file mode 100644 (file)
index 0000000..07e35ca
--- /dev/null
@@ -0,0 +1,154 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_CIRCLESHAPE_HPP
+#define SFML_CIRCLESHAPE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Shape.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Specialized shape representing a circle
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API CircleShape : public Shape
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// \param radius     Radius of the circle
+    /// \param pointCount Number of points composing the circle
+    ///
+    ////////////////////////////////////////////////////////////
+    explicit CircleShape(float radius = 0, unsigned int pointCount = 30);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the radius of the circle
+    ///
+    /// \param radius New radius of the circle
+    ///
+    /// \see getRadius
+    ///
+    ////////////////////////////////////////////////////////////
+    void setRadius(float radius);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the radius of the circle
+    ///
+    /// \return Radius of the circle
+    ///
+    /// \see setRadius
+    ///
+    ////////////////////////////////////////////////////////////
+    float getRadius() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the number of points of the circle
+    ///
+    /// \param count New number of points of the circle
+    ///
+    /// \see getPointCount
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPointCount(unsigned int count);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the number of points of the circle
+    ///
+    /// \return Number of points of the circle
+    ///
+    /// \see setPointCount
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual unsigned int getPointCount() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a point of the circle
+    ///
+    /// The returned point is in local coordinates, that is,
+    /// the shape's transforms (position, rotation, scale) are
+    /// not taken into account.
+    /// The result is undefined if \a index is out of the valid range.
+    ///
+    /// \param index Index of the point to get, in range [0 .. getPointCount() - 1]
+    ///
+    /// \return index-th point of the shape
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2f getPoint(unsigned int index) const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    float        m_radius;     ///< Radius of the circle
+    unsigned int m_pointCount; ///< Number of points composing the circle
+};
+
+} // namespace sf
+
+
+#endif // SFML_CIRCLESHAPE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::CircleShape
+/// \ingroup graphics
+///
+/// This class inherits all the functions of sf::Transformable
+/// (position, rotation, scale, bounds, ...) as well as the
+/// functions of sf::Shape (outline, color, texture, ...).
+///
+/// Usage example:
+/// \code
+/// sf::CircleShape circle;
+/// circle.setRadius(150);
+/// circle.setOutlineColor(sf::Color::Red);
+/// circle.setOutlineThickness(5);
+/// circle.setPosition(10, 20);
+/// ...
+/// window.draw(circle);
+/// \endcode
+///
+/// Since the graphics card can't draw perfect circles, we have to
+/// fake them with multiple triangles connected to each other. The
+/// "points count" property of sf::CircleShape defines how many of these
+/// triangles to use, and therefore defines the quality of the circle.
+///
+/// The number of points can also be used for another purpose; with
+/// small numbers you can create any regular polygon shape:
+/// equilateral triangle, square, pentagon, hexagon, ...
+///
+/// \see sf::Shape, sf::RectangleShape, sf::ConvexShape
+///
+////////////////////////////////////////////////////////////
index 17c62fda0be7136b8e7b6b9b1d05f5aff975edfd..8c81e3cef2e9a773997ef89b77e49a5001c785b9 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/Graphics/Export.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Color is an utility class for manipulating
-/// 32-bits RGBA colors
+/// \brief Utility class for manipulating RGBA colors
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Color
+class SFML_GRAPHICS_API Color
 {
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    Color();
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Construct the color from its 4 RGBA components
+    /// \brief Default constructor
     ///
-    /// \param R : Red component   (0 .. 255)
-    /// \param G : Green component (0 .. 255)
-    /// \param B : Blue component  (0 .. 255)
-    /// \param A : Alpha component (0 .. 255) (255 by default)
+    /// Constructs an opaque black color. It is equivalent to
+    /// sf::Color(0, 0, 0, 255).
     ///
     ////////////////////////////////////////////////////////////
-    Color(Uint8 R, Uint8 G, Uint8 B, Uint8 A = 255);
-
-    ////////////////////////////////////////////////////////////
-    /// Operator += overload to add a color
-    ///
-    /// \param Other : Color to add
-    ///
-    /// \return Component-wise saturated addition of the two colors
-    ///
-    ////////////////////////////////////////////////////////////
-    Color& operator +=(const Color& Other);
-
-    ////////////////////////////////////////////////////////////
-    /// Operator *= overload to modulate a color
-    ///
-    /// \param Other : Color to modulate
-    ///
-    /// \return Component-wise multiplication of the two colors
-    ///
-    ////////////////////////////////////////////////////////////
-    Color& operator *=(const Color& Other);
-
-    ////////////////////////////////////////////////////////////
-    /// Compare two colors (for equality)
-    ///
-    /// \param Other : Color to compare
-    ///
-    /// \return True if colors are equal
-    ///
-    ////////////////////////////////////////////////////////////
-    bool operator ==(const Color& Other) const;
+    Color();
 
     ////////////////////////////////////////////////////////////
-    /// Compare two colors (for difference)
-    ///
-    /// \param Other : Color to compare
+    /// \brief Construct the color from its 4 RGBA components
     ///
-    /// \return True if colors are different
+    /// \param red   Red component (in the range [0, 255])
+    /// \param green Green component (in the range [0, 255])
+    /// \param blue  Blue component (in the range [0, 255])
+    /// \param alpha Alpha (opacity) component (in the range [0, 255])
     ///
     ////////////////////////////////////////////////////////////
-    bool operator !=(const Color& Other) const;
+    Color(Uint8 red, Uint8 green, Uint8 blue, Uint8 alpha = 255);
 
     ////////////////////////////////////////////////////////////
     // Static member data
     ////////////////////////////////////////////////////////////
-    static const Color Black;   ///< Black predefined color
-    static const Color White;   ///< White predefined color
-    static const Color Red;     ///< Red predefined color
-    static const Color Green;   ///< Green predefined color
-    static const Color Blue;    ///< Blue predefined color
-    static const Color Yellow;  ///< Yellow predefined color
-    static const Color Magenta; ///< Magenta predefined color
-    static const Color Cyan;    ///< Cyan predefined color
+    static const Color Black;       ///< Black predefined color
+    static const Color White;       ///< White predefined color
+    static const Color Red;         ///< Red predefined color
+    static const Color Green;       ///< Green predefined color
+    static const Color Blue;        ///< Blue predefined color
+    static const Color Yellow;      ///< Yellow predefined color
+    static const Color Magenta;     ///< Magenta predefined color
+    static const Color Cyan;        ///< Cyan predefined color
+    static const Color Transparent; ///< Transparent (black) predefined color
 
     ////////////////////////////////////////////////////////////
     // Member data
@@ -116,32 +80,180 @@ public :
     Uint8 r; ///< Red component
     Uint8 g; ///< Green component
     Uint8 b; ///< Blue component
-    Uint8 a; ///< Alpha (transparency) component
+    Uint8 a; ///< Alpha (opacity) component
 };
 
 ////////////////////////////////////////////////////////////
-/// Operator + overload to add two colors
+/// \relates Color
+/// \brief Overload of the == operator
+///
+/// This operator compares two colors and check if they are equal.
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return True if colors are equal, false if they are different
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API bool operator ==(const Color& left, const Color& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Color
+/// \brief Overload of the != operator
+///
+/// This operator compares two colors and check if they are different.
 ///
-/// \param Color1 : First color
-/// \param Color2 : Second color
+/// \param left  Left operand
+/// \param right Right operand
 ///
-/// \return Component-wise saturated addition of the two colors
+/// \return True if colors are different, false if they are equal
 ///
 ////////////////////////////////////////////////////////////
-SFML_API Color operator +(const Color& Color1, const Color& Color2);
+SFML_GRAPHICS_API bool operator !=(const Color& left, const Color& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator * overload to modulate two colors
+/// \relates Color
+/// \brief Overload of the binary + operator
 ///
-/// \param Color1 : First color
-/// \param Color2 : Second color
+/// This operator returns the component-wise sum of two colors.
+/// Components that exceed 255 are clamped to 255.
 ///
-/// \return Component-wise multiplication of the two colors
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return Result of \a left + \a right
 ///
 ////////////////////////////////////////////////////////////
-SFML_API Color operator *(const Color& Color1, const Color& Color2);
+SFML_GRAPHICS_API Color operator +(const Color& left, const Color& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Color
+/// \brief Overload of the binary - operator
+///
+/// This operator returns the component-wise subtraction of two colors.
+/// Components below 0 are clamped to 0.
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return Result of \a left - \a right
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Color operator -(const Color& left, const Color& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Color
+/// \brief Overload of the binary * operator
+///
+/// This operator returns the component-wise multiplication
+/// (also called "modulation") of two colors.
+/// Components are then divided by 255 so that the result is
+/// still in the range [0, 255].
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return Result of \a left * \a right
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Color operator *(const Color& left, const Color& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Color
+/// \brief Overload of the binary += operator
+///
+/// This operator computes the component-wise sum of two colors,
+/// and assigns the result to the left operand.
+/// Components that exceed 255 are clamped to 255.
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return Reference to \a left
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Color& operator +=(Color& left, const Color& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Color
+/// \brief Overload of the binary -= operator
+///
+/// This operator computes the component-wise subtraction of two colors,
+/// and assigns the result to the left operand.
+/// Components below 0 are clamped to 0.
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return Reference to \a left
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Color& operator -=(Color& left, const Color& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Color
+/// \brief Overload of the binary *= operator
+///
+/// This operator returns the component-wise multiplication
+/// (also called "modulation") of two colors, and assigns
+/// the result to the left operand.
+/// Components are then divided by 255 so that the result is
+/// still in the range [0, 255].
+///
+/// \param left  Left operand
+/// \param right Right operand
+///
+/// \return Reference to \a left
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Color& operator *=(Color& left, const Color& right);
 
 } // namespace sf
 
 
 #endif // SFML_COLOR_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Color
+/// \ingroup graphics
+///
+/// sf::Color is a simple color class composed of 4 components:
+/// \li Red
+/// \li Green
+/// \li Blue
+/// \li Alpha (opacity)
+///
+/// Each component is a public member, an unsigned integer in
+/// the range [0, 255]. Thus, colors can be constructed and
+/// manipulated very easily:
+///
+/// \code
+/// sf::Color color(255, 0, 0); // red
+/// color.r = 0;                // make it black
+/// color.b = 128;              // make it dark blue
+/// \endcode
+///
+/// The fourth component of colors, named "alpha", represents
+/// the opacity of the color. A color with an alpha value of
+/// 255 will be fully opaque, while an alpha value of 0 will
+/// make a color fully transparent, whatever the value of the
+/// other components is.
+///
+/// The most common colors are already defined as static variables:
+/// \code
+/// sf::Color black       = sf::Color::Black;
+/// sf::Color white       = sf::Color::White;
+/// sf::Color red         = sf::Color::Red;
+/// sf::Color green       = sf::Color::Green;
+/// sf::Color blue        = sf::Color::Blue;
+/// sf::Color yellow      = sf::Color::Yellow;
+/// sf::Color magenta     = sf::Color::Magenta;
+/// sf::Color cyan        = sf::Color::Cyan;
+/// sf::Color transparent = sf::Color::Transparent;
+/// \endcode
+///
+/// Colors can also be added and modulated (multiplied) using the
+/// overloaded operators + and *.
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/ConvexShape.hpp b/dependencies64/sfml/include/SFML/Graphics/ConvexShape.hpp
new file mode 100644 (file)
index 0000000..080ca04
--- /dev/null
@@ -0,0 +1,153 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_CONVEXSHAPE_HPP
+#define SFML_CONVEXSHAPE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Shape.hpp>
+#include <vector>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Specialized shape representing a convex polygon
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API ConvexShape : public Shape
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// \param pointCount Number of points of the polygon
+    ///
+    ////////////////////////////////////////////////////////////
+    explicit ConvexShape(unsigned int pointCount = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the number of points of the polygon
+    ///
+    /// \a count must be greater than 2 to define a valid shape.
+    ///
+    /// \param count New number of points of the polygon
+    ///
+    /// \see getPointCount
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPointCount(unsigned int count);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the number of points of the polygon
+    ///
+    /// \return Number of points of the polygon
+    ///
+    /// \see setPointCount
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual unsigned int getPointCount() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the position of a point
+    ///
+    /// Don't forget that the polygon must remain convex, and
+    /// the points need to stay ordered!
+    /// setPointCount must be called first in order to set the total
+    /// number of points. The result is undefined if \a index is out
+    /// of the valid range.
+    ///
+    /// \param index Index of the point to change, in range [0 .. getPointCount() - 1]
+    /// \param point New position of the point
+    ///
+    /// \see getPoint
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPoint(unsigned int index, const Vector2f& point);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of a point
+    ///
+    /// The returned point is in local coordinates, that is,
+    /// the shape's transforms (position, rotation, scale) are
+    /// not taken into account.
+    /// The result is undefined if \a index is out of the valid range.
+    ///
+    /// \param index Index of the point to get, in range [0 .. getPointCount() - 1]
+    ///
+    /// \return Position of the index-th point of the polygon
+    ///
+    /// \see setPoint
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2f getPoint(unsigned int index) const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    std::vector<Vector2f> m_points; ///< Points composing the convex polygon
+};
+
+} // namespace sf
+
+
+#endif // SFML_CONVEXSHAPE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::ConvexShape
+/// \ingroup graphics
+///
+/// This class inherits all the functions of sf::Transformable
+/// (position, rotation, scale, bounds, ...) as well as the
+/// functions of sf::Shape (outline, color, texture, ...).
+///
+/// It is important to keep in mind that a convex shape must
+/// always be... convex, otherwise it may not be drawn correctly.
+/// Moreover, the points must be defined in order; using a random
+/// order would result in an incorrect shape.
+///
+/// Usage example:
+/// \code
+/// sf::ConvexShape polygon;
+/// polygon.setPointCount(3);
+/// polygon.setPoint(0, sf::Vector2f(0, 0));
+/// polygon.setPoint(1, sf::Vector2f(0, 10));
+/// polygon.setPoint(2, sf::Vector2f(25, 5));
+/// polygon.setOutlineColor(sf::Color::Red);
+/// polygon.setOutlineThickness(5);
+/// polygon.setPosition(10, 20);
+/// ...
+/// window.draw(polygon);
+/// \endcode
+///
+/// \see sf::Shape, sf::RectangleShape, sf::CircleShape
+///
+////////////////////////////////////////////////////////////
index b1b979c8a3b8a263b7e8692edc11a1dc0135913b..8e30a6d678524eda861cd03161d90524ede0645f 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
@@ -28,9 +28,8 @@
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/Vector2.hpp>
-#include <SFML/Graphics/Color.hpp>
-#include <SFML/Graphics/Matrix3.hpp>
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/RenderStates.hpp>
 
 
 namespace sf
@@ -38,324 +37,90 @@ namespace sf
 class RenderTarget;
 
 ////////////////////////////////////////////////////////////
-/// Enumerate the blending modes for drawable objects
+/// \brief Abstract base class for objects that can be drawn
+///        to a render target
+///
 ////////////////////////////////////////////////////////////
-namespace Blend
+class SFML_GRAPHICS_API Drawable
 {
-    enum Mode
-    {
-        Alpha,    ///< Pixel = Src * a + Dest * (1 - a)
-        Add,      ///< Pixel = Src + Dest
-        Multiply, ///< Pixel = Src * Dest
-        None      ///< No blending
-    };
-}
+public:
 
-////////////////////////////////////////////////////////////
-/// Abstract base class for every object that can be drawn
-/// into a render window
-////////////////////////////////////////////////////////////
-class SFML_API Drawable
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    /// \param Position : Position of the object (0, 0 by default)
-    /// \param Scale :    Scale factor (1, 1 by default)
-    /// \param Rotation : Orientation, in degrees (0 by default)
-    /// \param Col :      Color of the object (white by default)
-    ///
-    ////////////////////////////////////////////////////////////
-    Drawable(const Vector2f& Position = Vector2f(0, 0), const Vector2f& Scale = Vector2f(1, 1), float Rotation = 0.f, const Color& Col = Color(255, 255, 255, 255));
-
-    ////////////////////////////////////////////////////////////
-    /// Virtual destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual ~Drawable();
-
-    ////////////////////////////////////////////////////////////
-    /// Set the position of the object (take 2 values)
-    ///
-    /// \param X : New X coordinate
-    /// \param Y : New Y coordinate
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetPosition(float X, float Y);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the position of the object (take a 2D vector)
-    ///
-    /// \param Position : New position
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetPosition(const Vector2f& Position);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the X position of the object
-    ///
-    /// \param X : New X coordinate
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetX(float X);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the Y position of the object
-    ///
-    /// \param Y : New Y coordinate
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetY(float Y);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the scale of the object (take 2 values)
-    ///
-    /// \param ScaleX : New horizontal scale (must be strictly positive)
-    /// \param ScaleY : New vertical scale (must be strictly positive)
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetScale(float ScaleX, float ScaleY);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the scale of the object (take a 2D vector)
-    ///
-    /// \param Scale : New scale (both values must be strictly positive)
-    ///
     ////////////////////////////////////////////////////////////
-    void SetScale(const Vector2f& Scale);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the X scale factor of the object
-    ///
-    /// \param X : New X scale factor
+    /// \brief Virtual destructor
     ///
     ////////////////////////////////////////////////////////////
-    void SetScaleX(float FactorX);
+    virtual ~Drawable() {}
 
-    ////////////////////////////////////////////////////////////
-    /// Set the Y scale factor of the object
-    ///
-    /// \param Y : New Y scale factor
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetScaleY(float FactorY);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the center of the object, in coordinates relative to the
-    /// top-left of the object (take 2 values).
-    /// The default center is (0, 0)
-    ///
-    /// \param CenterX : X coordinate of the center
-    /// \param CenterY : Y coordinate of the center
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetCenter(float CenterX, float CenterY);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the center of the object, in coordinates relative to the
-    /// top-left of the object (take a 2D vector).
-    /// The default center is (0, 0)
-    ///
-    /// \param Center : New center
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetCenter(const Vector2f& Center);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the orientation of the object
-    ///
-    /// \param Rotation : Angle of rotation, in degrees
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetRotation(float Rotation);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the color of the object.
-    /// The default color is white
-    ///
-    /// \param Col : New color
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetColor(const Color& Col);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the blending mode for the object.
-    /// The default blend mode is Blend::Alpha
-    ///
-    /// \param Mode : New blending mode
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetBlendMode(Blend::Mode Mode);
-
-    ////////////////////////////////////////////////////////////
-    /// Get the position of the object
-    ///
-    /// \return Current position
-    ///
-    ////////////////////////////////////////////////////////////
-    const Vector2f& GetPosition() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the current scale of the object
-    ///
-    /// \return Current scale factor (always positive)
-    ///
-    ////////////////////////////////////////////////////////////
-    const Vector2f& GetScale() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the center of the object
-    ///
-    /// \return Current position of the center
-    ///
-    ////////////////////////////////////////////////////////////
-    const Vector2f& GetCenter() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the orientation of the object.
-    /// Rotation is always in the range [0, 360]
-    ///
-    /// \return Current rotation, in degrees
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetRotation() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the color of the object
-    ///
-    /// \return Current color
-    ///
-    ////////////////////////////////////////////////////////////
-    const Color& GetColor() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the current blending mode
-    ///
-    /// \return Current blending mode
-    ///
-    ////////////////////////////////////////////////////////////
-    Blend::Mode GetBlendMode() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Move the object of a given offset (take 2 values)
-    ///
-    /// \param OffsetX : X offset
-    /// \param OffsetY : Y offset
-    ///
-    ////////////////////////////////////////////////////////////
-    void Move(float OffsetX, float OffsetY);
-
-    ////////////////////////////////////////////////////////////
-    /// Move the object of a given offset (take a 2D vector)
-    ///
-    /// \param Offset : Amount of units to move the object of
-    ///
-    ////////////////////////////////////////////////////////////
-    void Move(const Vector2f& Offset);
-
-    ////////////////////////////////////////////////////////////
-    /// Scale the object (take 2 values)
-    ///
-    /// \param FactorX : Scaling factor on X (must be strictly positive)
-    /// \param FactorY : Scaling factor on Y (must be strictly positive)
-    ///
-    ////////////////////////////////////////////////////////////
-    void Scale(float FactorX, float FactorY);
-
-    ////////////////////////////////////////////////////////////
-    /// Scale the object (take a 2D vector)
-    ///
-    /// \param Factor : Scaling factors (both values must be strictly positive)
-    ///
-    ////////////////////////////////////////////////////////////
-    void Scale(const Vector2f& Factor);
-
-    ////////////////////////////////////////////////////////////
-    /// Rotate the object
-    ///
-    /// \param Angle : Angle of rotation, in degrees
-    ///
-    ////////////////////////////////////////////////////////////
-    void Rotate(float Angle);
-
-    ////////////////////////////////////////////////////////////
-    /// Transform a point from global coordinates into local coordinates
-    /// (ie it applies the inverse of object's center, translation, rotation and scale to the point)
-    ///
-    /// \param Point : Point to transform
-    ///
-    /// \return Transformed point
-    ///
-    ////////////////////////////////////////////////////////////
-    sf::Vector2f TransformToLocal(const sf::Vector2f& Point) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Transform a point from local coordinates into global coordinates
-    /// (ie it applies the object's center, translation, rotation and scale to the point)
-    ///
-    /// \param Point : Point to transform
-    ///
-    /// \return Transformed point
-    ///
-    ////////////////////////////////////////////////////////////
-    sf::Vector2f TransformToGlobal(const sf::Vector2f& Point) const;
-
-protected :
-
-    ////////////////////////////////////////////////////////////
-    /// Get the transform matrix of the drawable
-    ///
-    /// \return Transform matrix
-    ///
-    ////////////////////////////////////////////////////////////
-    const Matrix3& GetMatrix() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the inverse transform matrix of the drawable
-    ///
-    /// \return Inverse transform matrix
-    ///
-    ////////////////////////////////////////////////////////////
-    const Matrix3& GetInverseMatrix() const;
-
-private :
+protected:
 
     friend class RenderTarget;
 
     ////////////////////////////////////////////////////////////
-    /// Draw the object into the specified window
-    ///
-    /// \param Target : Target into which render the object
+    /// \brief Draw the object to a render target
     ///
-    ////////////////////////////////////////////////////////////
-    void Draw(RenderTarget& Target) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Render the specific geometry of the object
+    /// This is a pure virtual function that has to be implemented
+    /// by the derived class to define how the drawable should be
+    /// drawn.
     ///
-    /// \param Target : Target into which render the object
+    /// \param target Render target to draw to
+    /// \param states Current render states
     ///
     ////////////////////////////////////////////////////////////
-    virtual void Render(RenderTarget& Target) const = 0;
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    Vector2f        myPosition;      ///< Position of the object on screen
-    Vector2f        myScale;         ///< Scale of the object
-    Vector2f        myCenter;        ///< Origin of translation / rotation / scaling of the object
-    float           myRotation;      ///< Orientation of the object, in degrees
-    Color           myColor;         ///< Overlay color of the object
-    Blend::Mode     myBlendMode;     ///< Blending mode
-    mutable bool    myNeedUpdate;    ///< Do we need to recompute the transform matrix ?
-    mutable bool    myInvNeedUpdate; ///< Do we need to recompute the inverse transform matrix ?
-    mutable Matrix3 myMatrix;        ///< Precomputed transform matrix gathering the translation / rotation / scale / center
-    mutable Matrix3 myInvMatrix;     ///< Precomputed inverse transform matrix gathering the translation / rotation / scale / center
+    virtual void draw(RenderTarget& target, RenderStates states) const = 0;
 };
 
 } // namespace sf
 
 
 #endif // SFML_DRAWABLE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Drawable
+/// \ingroup graphics
+///
+/// sf::Drawable is a very simple base class that allows objects
+/// of derived classes to be drawn to a sf::RenderTarget.
+///
+/// All you have to do in your derived class is to override the
+/// draw virtual function.
+///
+/// Note that inheriting from sf::Drawable is not mandatory,
+/// but it allows this nice syntax "window.draw(object)" rather
+/// than "object.draw(window)", which is more consistent with other
+/// SFML classes.
+///
+/// Example:
+/// \code
+/// class MyDrawable : public sf::Drawable
+/// {
+/// public:
+///
+///    ...
+///
+/// private:
+///
+///     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
+///     {
+///         // You can draw other high-level objects
+///         target.draw(m_sprite, states);
+///
+///         // ... or use the low-level API
+///         states.texture = &m_texture;
+///         target.draw(m_vertices, states);
+///
+///         // ... or draw with OpenGL directly
+///         glBegin(GL_QUADS);
+///         ...
+///         glEnd();
+///     }
+///
+///     sf::Sprite m_sprite;
+///     sf::Texture m_texture;
+///     sf::VertexArray m_vertices;
+/// };
+/// \endcode
+///
+/// \see sf::RenderTarget
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Export.hpp b/dependencies64/sfml/include/SFML/Graphics/Export.hpp
new file mode 100644 (file)
index 0000000..3109fcd
--- /dev/null
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_GRAPHICS_EXPORT_HPP
+#define SFML_GRAPHICS_EXPORT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_GRAPHICS_EXPORTS)
+
+    #define SFML_GRAPHICS_API SFML_API_EXPORT
+
+#else
+
+    #define SFML_GRAPHICS_API SFML_API_IMPORT
+
+#endif
+
+
+#endif // SFML_GRAPHICS_EXPORT_HPP
index 1da1667c5d9f77f2165feb87f82024f2ff2350ef..8b360c920f81c9550d8559650bafc94cbb7fa1c1 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/Resource.hpp>
-#include <SFML/System/Vector2.hpp>
-#include <SFML/System/Unicode.hpp>
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Glyph.hpp>
-#include <SFML/Graphics/Image.hpp>
+#include <SFML/Graphics/Texture.hpp>
 #include <SFML/Graphics/Rect.hpp>
+#include <SFML/System/Vector2.hpp>
+#include <SFML/System/String.hpp>
 #include <map>
 #include <string>
+#include <vector>
 
 
 namespace sf
 {
-class String;
+class InputStream;
 
-namespace priv
-{
-class FontLoader;
-}
 ////////////////////////////////////////////////////////////
-/// Font is the low-level class for loading and
-/// manipulating character fonts. This class is meant to
-/// be used by sf::String
+/// \brief Class for loading and manipulating character fonts
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Font : public Resource<Font>
+class SFML_GRAPHICS_API Font
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Holds various information about a font
+    ///
+    ////////////////////////////////////////////////////////////
+    struct Info
+    {
+        std::string family; ///< The font family
+    };
+
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor defines an empty font
     ///
     ////////////////////////////////////////////////////////////
     Font();
 
     ////////////////////////////////////////////////////////////
-    /// Load the font from a file
+    /// \brief Copy constructor
+    ///
+    /// \param copy Instance to copy
     ///
-    /// \param Filename : Font file to load
-    /// \param CharSize : Size of characters in bitmap - the bigger, the higher quality (30 by default)
-    /// \param Charset :  Characters set to generate (by default, contains the ISO-8859-1 printable characters)
+    ////////////////////////////////////////////////////////////
+    Font(const Font& copy);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
     ///
-    /// \return True if loading was successful
+    /// Cleans up all the internal resources used by the font
     ///
     ////////////////////////////////////////////////////////////
-    bool LoadFromFile(const std::string& Filename, unsigned int CharSize = 30, const Unicode::Text& Charset = ourDefaultCharset);
+    ~Font();
 
     ////////////////////////////////////////////////////////////
-    /// Load the font from a file in memory
+    /// \brief Load the font from a file
     ///
-    /// \param Data :        Pointer to the data to load
-    /// \param SizeInBytes : Size of the data, in bytes
-    /// \param CharSize :    Size of characters in bitmap - the bigger, the higher quality (30 by default)
-    /// \param Charset :     Characters set to generate (by default, contains the ISO-8859-1 printable characters)
+    /// The supported font formats are: TrueType, Type 1, CFF,
+    /// OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42.
+    /// Note that this function know nothing about the standard
+    /// fonts installed on the user's system, thus you can't
+    /// load them directly.
     ///
-    /// \return True if loading was successful
+    /// \param filename Path of the font file to load
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromMemory, loadFromStream
     ///
     ////////////////////////////////////////////////////////////
-    bool LoadFromMemory(const char* Data, std::size_t SizeInBytes, unsigned int CharSize = 30, const Unicode::Text& Charset = ourDefaultCharset);
+    bool loadFromFile(const std::string& filename);
 
     ////////////////////////////////////////////////////////////
-    /// Get the base size of characters in the font;
-    /// All glyphs dimensions are based on this value
+    /// \brief Load the font from a file in memory
+    ///
+    /// The supported font formats are: TrueType, Type 1, CFF,
+    /// OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42.
+    /// Warning: SFML cannot preload all the font data in this
+    /// function, so the buffer pointed by \a data has to remain
+    /// valid as long as the font is used.
+    ///
+    /// \param data        Pointer to the file data in memory
+    /// \param sizeInBytes Size of the data to load, in bytes
     ///
-    /// \return Base size of characters
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromStream
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetCharacterSize() const;
+    bool loadFromMemory(const void* data, std::size_t sizeInBytes);
 
     ////////////////////////////////////////////////////////////
-    /// Get the description of a glyph (character)
-    /// given by its unicode value
+    /// \brief Load the font from a custom stream
+    ///
+    /// The supported font formats are: TrueType, Type 1, CFF,
+    /// OpenType, SFNT, X11 PCF, Windows FNT, BDF, PFR and Type 42.
+    /// Warning: SFML cannot preload all the font data in this
+    /// function, so the contents of \a stream have to remain
+    /// valid as long as the font is used.
+    ///
+    /// \param stream Source stream to read from
     ///
-    /// \param CodePoint : Unicode value of the character to get
+    /// \return True if loading succeeded, false if it failed
     ///
-    /// \return Glyph's visual settings, or an invalid glyph if character not found
+    /// \see loadFromFile, loadFromMemory
     ///
     ////////////////////////////////////////////////////////////
-    const Glyph& GetGlyph(Uint32 CodePoint) const;
+    bool loadFromStream(InputStream& stream);
 
     ////////////////////////////////////////////////////////////
-    /// Get the image containing the rendered characters (glyphs)
+    /// \brief Get the font information
+    ///
+    /// \return A structure that holds the font information
+    ///
+    ////////////////////////////////////////////////////////////
+    const Info& getInfo() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Retrieve a glyph of the font
+    ///
+    /// If the font is a bitmap font, not all character sizes
+    /// might be available. If the glyph is not available at the
+    /// requested size, an empty glyph is returned.
     ///
-    /// \return Image containing glyphs
+    /// \param codePoint     Unicode code point of the character to get
+    /// \param characterSize Reference character size
+    /// \param bold          Retrieve the bold version or the regular one?
+    ///
+    /// \return The glyph corresponding to \a codePoint and \a characterSize
     ///
     ////////////////////////////////////////////////////////////
-    const Image& GetImage() const;
+    const Glyph& getGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the SFML default built-in font (Arial)
+    /// \brief Get the kerning offset of two glyphs
+    ///
+    /// The kerning is an extra offset (negative) to apply between two
+    /// glyphs when rendering them, to make the pair look more "natural".
+    /// For example, the pair "AV" have a special kerning to make them
+    /// closer than other characters. Most of the glyphs pairs have a
+    /// kerning offset of zero, though.
     ///
-    /// \return Instance of the default font
+    /// \param first         Unicode code point of the first character
+    /// \param second        Unicode code point of the second character
+    /// \param characterSize Reference character size
+    ///
+    /// \return Kerning value for \a first and \a second, in pixels
     ///
     ////////////////////////////////////////////////////////////
-    static const Font& GetDefaultFont();
+    float getKerning(Uint32 first, Uint32 second, unsigned int characterSize) const;
 
-private :
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the line spacing
+    ///
+    /// Line spacing is the vertical offset to apply between two
+    /// consecutive lines of text.
+    ///
+    /// \param characterSize Reference character size
+    ///
+    /// \return Line spacing, in pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    float getLineSpacing(unsigned int characterSize) const;
 
-    friend class priv::FontLoader;
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the underline
+    ///
+    /// Underline position is the vertical offset to apply between the
+    /// baseline and the underline.
+    ///
+    /// \param characterSize Reference character size
+    ///
+    /// \return Underline position, in pixels
+    ///
+    /// \see getUnderlineThickness
+    ///
+    ////////////////////////////////////////////////////////////
+    float getUnderlinePosition(unsigned int characterSize) const;
 
     ////////////////////////////////////////////////////////////
-    // Static member data
+    /// \brief Get the thickness of the underline
+    ///
+    /// Underline thickness is the vertical size of the underline.
+    ///
+    /// \param characterSize Reference character size
+    ///
+    /// \return Underline thickness, in pixels
+    ///
+    /// \see getUnderlinePosition
+    ///
     ////////////////////////////////////////////////////////////
-    static Uint32 ourDefaultCharset[]; ///< The default charset (all printable ISO-8859-1 characters)
+    float getUnderlineThickness(unsigned int characterSize) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Retrieve the texture containing the loaded glyphs of a certain size
+    ///
+    /// The contents of the returned texture changes as more glyphs
+    /// are requested, thus it is not very relevant. It is mainly
+    /// used internally by sf::Text.
+    ///
+    /// \param characterSize Reference character size
+    ///
+    /// \return Texture containing the glyphs of the requested size
+    ///
+    ////////////////////////////////////////////////////////////
+    const Texture& getTexture(unsigned int characterSize) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of assignment operator
+    ///
+    /// \param right Instance to assign
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    Font& operator =(const Font& right);
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Structure defining a row of glyphs
+    ///
+    ////////////////////////////////////////////////////////////
+    struct Row
+    {
+        Row(unsigned int rowTop, unsigned int rowHeight) : width(0), top(rowTop), height(rowHeight) {}
+
+        unsigned int width;  ///< Current width of the row
+        unsigned int top;    ///< Y position of the row into the texture
+        unsigned int height; ///< Height of the row
+    };
+
+    ////////////////////////////////////////////////////////////
+    // Types
+    ////////////////////////////////////////////////////////////
+    typedef std::map<Uint32, Glyph> GlyphTable; ///< Table mapping a codepoint to its glyph
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Structure defining a page of glyphs
+    ///
+    ////////////////////////////////////////////////////////////
+    struct Page
+    {
+        Page();
+
+        GlyphTable       glyphs;  ///< Table mapping code points to their corresponding glyph
+        sf::Texture      texture; ///< Texture containing the pixels of the glyphs
+        unsigned int     nextRow; ///< Y position of the next new row in the texture
+        std::vector<Row> rows;    ///< List containing the position of all the existing rows
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Free all the internal resources
+    ///
+    ////////////////////////////////////////////////////////////
+    void cleanup();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load a new glyph and store it in the cache
+    ///
+    /// \param codePoint     Unicode code point of the character to load
+    /// \param characterSize Reference character size
+    /// \param bold          Retrieve the bold version or the regular one?
+    ///
+    /// \return The glyph corresponding to \a codePoint and \a characterSize
+    ///
+    ////////////////////////////////////////////////////////////
+    Glyph loadGlyph(Uint32 codePoint, unsigned int characterSize, bool bold) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Find a suitable rectangle within the texture for a glyph
+    ///
+    /// \param page   Page of glyphs to search in
+    /// \param width  Width of the rectangle
+    /// \param height Height of the rectangle
+    ///
+    /// \return Found rectangle within the texture
+    ///
+    ////////////////////////////////////////////////////////////
+    IntRect findGlyphRect(Page& page, unsigned int width, unsigned int height) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Make sure that the given size is the current one
+    ///
+    /// \param characterSize Reference character size
+    ///
+    /// \return True on success, false if any error happened
+    ///
+    ////////////////////////////////////////////////////////////
+    bool setCurrentSize(unsigned int characterSize) const;
+
+    ////////////////////////////////////////////////////////////
+    // Types
+    ////////////////////////////////////////////////////////////
+    typedef std::map<unsigned int, Page> PageTable; ///< Table mapping a character size to its page (texture)
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    Image                   myTexture;  ///< Texture holding the bitmap font
-    unsigned int            myCharSize; ///< Size of characters in the bitmap font
-    std::map<Uint32, Glyph> myGlyphs;   ///< Rendering settings of each character (glyph)
+    void*                      m_library;     ///< Pointer to the internal library interface (it is typeless to avoid exposing implementation details)
+    void*                      m_face;        ///< Pointer to the internal font face (it is typeless to avoid exposing implementation details)
+    void*                      m_streamRec;   ///< Pointer to the stream rec instance (it is typeless to avoid exposing implementation details)
+    int*                       m_refCount;    ///< Reference counter used by implicit sharing
+    Info                       m_info;        ///< Information about the font
+    mutable PageTable          m_pages;       ///< Table containing the glyphs pages by character size
+    mutable std::vector<Uint8> m_pixelBuffer; ///< Pixel buffer holding a glyph's pixels before being written to the texture
+    #ifdef SFML_SYSTEM_ANDROID
+    void*                      m_stream; ///< Asset file streamer (if loaded from file)
+    #endif
 };
 
 } // namespace sf
 
 
 #endif // SFML_FONT_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Font
+/// \ingroup graphics
+///
+/// Fonts can be loaded from a file, from memory or from a custom
+/// stream, and supports the most common types of fonts. See
+/// the loadFromFile function for the complete list of supported formats.
+///
+/// Once it is loaded, a sf::Font instance provides three
+/// types of information about the font:
+/// \li Global metrics, such as the line spacing
+/// \li Per-glyph metrics, such as bounding box or kerning
+/// \li Pixel representation of glyphs
+///
+/// Fonts alone are not very useful: they hold the font data
+/// but cannot make anything useful of it. To do so you need to
+/// use the sf::Text class, which is able to properly output text
+/// with several options such as character size, style, color,
+/// position, rotation, etc.
+/// This separation allows more flexibility and better performances:
+/// indeed a sf::Font is a heavy resource, and any operation on it
+/// is slow (often too slow for real-time applications). On the other
+/// side, a sf::Text is a lightweight object which can combine the
+/// glyphs data and metrics of a sf::Font to display any text on a
+/// render target.
+/// Note that it is also possible to bind several sf::Text instances
+/// to the same sf::Font.
+///
+/// It is important to note that the sf::Text instance doesn't
+/// copy the font that it uses, it only keeps a reference to it.
+/// Thus, a sf::Font must not be destructed while it is
+/// used by a sf::Text (i.e. never write a function that
+/// uses a local sf::Font instance for creating a text).
+///
+/// Usage example:
+/// \code
+/// // Declare a new font
+/// sf::Font font;
+///
+/// // Load it from a file
+/// if (!font.loadFromFile("arial.ttf"))
+/// {
+///     // error...
+/// }
+///
+/// // Create a text which uses our font
+/// sf::Text text1;
+/// text1.setFont(font);
+/// text1.setCharacterSize(30);
+/// text1.setStyle(sf::Text::Regular);
+///
+/// // Create another text using the same font, but with different parameters
+/// sf::Text text2;
+/// text2.setFont(font);
+/// text2.setCharacterSize(50);
+/// text1.setStyle(sf::Text::Italic);
+/// \endcode
+///
+/// Apart from loading font files, and passing them to instances
+/// of sf::Text, you should normally not have to deal directly
+/// with this class. However, it may be useful to access the
+/// font metrics or rasterized glyphs for advanced usage.
+///
+/// Note that if the font is a bitmap font, it is not scalable,
+/// thus not all requested sizes will be available to use. This
+/// needs to be taken into consideration when using sf::Text.
+/// If you need to display text of a certain size, make sure the
+/// corresponding bitmap font that supports that size is used.
+///
+/// \see sf::Text
+///
+////////////////////////////////////////////////////////////
index 9ab19a82c8891d12f64f0e8befef5938efec5eba..bdc3357ef3f91ab3f72b8f493e22b7ebc5b4d7c9 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Rect.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Structure describing a glyph (a visual character)
+/// \brief Structure describing a glyph
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Glyph
+class SFML_GRAPHICS_API Glyph
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
     ///
     ////////////////////////////////////////////////////////////
-    Glyph() : Advance(0) {}
+    Glyph() : advance(0) {}
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    int       Advance;   ///< Offset to move horizontically to the next character
-    IntRect   Rectangle; ///< Bounding rectangle of the glyph, in relative coordinates
-    FloatRect TexCoords; ///< Texture coordinates of the glyph inside the bitmap font
+    float     advance;     ///< Offset to move horizontally to the next character
+    FloatRect bounds;      ///< Bounding rectangle of the glyph, in coordinates relative to the baseline
+    IntRect   textureRect; ///< Texture coordinates of the glyph inside the font's texture
 };
 
 } // namespace sf
 
 
 #endif // SFML_GLYPH_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Glyph
+/// \ingroup graphics
+///
+/// A glyph is the visual representation of a character.
+///
+/// The sf::Glyph structure provides the information needed
+/// to handle the glyph:
+/// \li its coordinates in the font's texture
+/// \li its bounding rectangle
+/// \li the offset to apply to get the starting position of the next glyph
+///
+/// \see sf::Font
+///
+////////////////////////////////////////////////////////////
index fee3df8344a95a83b39bb2f5b80bae709e81308d..82f77ef589677a3b1475da8a62a54102c5bac152 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
@@ -28,7 +28,7 @@
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/Resource.hpp>
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Color.hpp>
 #include <SFML/Graphics/Rect.hpp>
 #include <string>
 
 namespace sf
 {
-class RenderWindow;
+class InputStream;
 
 ////////////////////////////////////////////////////////////
-/// Image is the low-level class for loading and
-/// manipulating images
+/// \brief Class for loading, manipulating and saving images
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Image : public Resource<Image>
+class SFML_GRAPHICS_API Image
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// Creates an empty image.
     ///
     ////////////////////////////////////////////////////////////
     Image();
 
     ////////////////////////////////////////////////////////////
-    /// Copy constructor
-    ///
-    /// \param Copy : instance to copy
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
-    Image(const Image& Copy);
+    ~Image();
 
     ////////////////////////////////////////////////////////////
-    /// Construct an empty image
+    /// \brief Create the image and fill it with a unique color
     ///
-    /// \param Width :  Image width
-    /// \param Height : Image height
-    /// \param Col :    Image color (black by default)
+    /// \param width  Width of the image
+    /// \param height Height of the image
+    /// \param color  Fill color
     ///
     ////////////////////////////////////////////////////////////
-    Image(unsigned int Width, unsigned int Height, const Color& Col = Color(0, 0, 0, 255));
+    void create(unsigned int width, unsigned int height, const Color& color = Color(0, 0, 0));
 
     ////////////////////////////////////////////////////////////
-    /// Construct the image from pixels in memory
+    /// \brief Create the image from an array of pixels
     ///
-    /// \param Width :  Image width
-    /// \param Height : Image height
-    /// \param Data :   Pointer to the pixels in memory (assumed format is RGBA)
+    /// The \a pixel array is assumed to contain 32-bits RGBA pixels,
+    /// and have the given \a width and \a height. If not, this is
+    /// an undefined behavior.
+    /// If \a pixels is null, an empty image is created.
     ///
-    ////////////////////////////////////////////////////////////
-    Image(unsigned int Width, unsigned int Height, const Uint8* Data);
-
-    ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \param width  Width of the image
+    /// \param height Height of the image
+    /// \param pixels Array of pixels to copy to the image
     ///
     ////////////////////////////////////////////////////////////
-    ~Image();
+    void create(unsigned int width, unsigned int height, const Uint8* pixels);
 
     ////////////////////////////////////////////////////////////
-    /// Load the image from a file
-    ///
-    /// \param Filename : Path of the image file to load
+    /// \brief Load the image from a file on disk
     ///
-    /// \return True if loading was successful
-    ///
-    ////////////////////////////////////////////////////////////
-    bool LoadFromFile(const std::string& Filename);
-
-    ////////////////////////////////////////////////////////////
-    /// Load the image from a file in memory
+    /// The supported image formats are bmp, png, tga, jpg, gif,
+    /// psd, hdr and pic. Some format options are not supported,
+    /// like progressive jpeg.
+    /// If this function fails, the image is left unchanged.
     ///
-    /// \param Data :        Pointer to the file data in memory
-    /// \param SizeInBytes : Size of the data to load, in bytes
+    /// \param filename Path of the image file to load
     ///
     /// \return True if loading was successful
     ///
-    ////////////////////////////////////////////////////////////
-    bool LoadFromMemory(const char* Data, std::size_t SizeInBytes);
-
-    ////////////////////////////////////////////////////////////
-    /// Load the image directly from an array of pixels
-    ///
-    /// \param Width :  Image width
-    /// \param Height : Image height
-    /// \param Data :   Pointer to the pixels in memory (assumed format is RGBA)
-    ///
-    /// \return True if loading was successful
+    /// \see loadFromMemory, loadFromStream, saveToFile
     ///
     ////////////////////////////////////////////////////////////
-    bool LoadFromPixels(unsigned int Width, unsigned int Height, const Uint8* Data);
+    bool loadFromFile(const std::string& filename);
 
     ////////////////////////////////////////////////////////////
-    /// Save the content of the image to a file
-    ///
-    /// \param Filename : Path of the file to save (overwritten if already exist)
+    /// \brief Load the image from a file in memory
     ///
-    /// \return True if saving was successful
+    /// The supported image formats are bmp, png, tga, jpg, gif,
+    /// psd, hdr and pic. Some format options are not supported,
+    /// like progressive jpeg.
+    /// If this function fails, the image is left unchanged.
     ///
-    ////////////////////////////////////////////////////////////
-    bool SaveToFile(const std::string& Filename) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Create an empty image
+    /// \param data Pointer to the file data in memory
+    /// \param size Size of the data to load, in bytes
     ///
-    /// \param Width :  Image width
-    /// \param Height : Image height
-    /// \param Col :    Image color (black by default)
+    /// \return True if loading was successful
     ///
-    /// \return True if creation was successful
+    /// \see loadFromFile, loadFromStream
     ///
     ////////////////////////////////////////////////////////////
-    bool Create(unsigned int Width, unsigned int Height, Color Col = Color(0, 0, 0, 255));
+    bool loadFromMemory(const void* data, std::size_t size);
 
     ////////////////////////////////////////////////////////////
-    /// Create transparency mask from a specified colorkey
+    /// \brief Load the image from a custom stream
     ///
-    /// \param ColorKey : Color to become transparent
-    /// \param Alpha :    Alpha value to use for transparent pixels (0 by default)
+    /// The supported image formats are bmp, png, tga, jpg, gif,
+    /// psd, hdr and pic. Some format options are not supported,
+    /// like progressive jpeg.
+    /// If this function fails, the image is left unchanged.
     ///
-    ////////////////////////////////////////////////////////////
-    void CreateMaskFromColor(Color ColorKey, Uint8 Alpha = 0);
-
-    ////////////////////////////////////////////////////////////
-    /// Copy pixels from another image onto this one.
-    /// This function does a slow pixel copy and should only
-    /// be used at initialization time
+    /// \param stream Source stream to read from
     ///
-    /// \param Source :     Source image to copy
-    /// \param DestX :      X coordinate of the destination position
-    /// \param DestY :      Y coordinate of the destination position
-    /// \param SourceRect : Sub-rectangle of the source image to copy (empty by default - entire image)
-    /// \param ApplyAlpha : Should the copy take in account the source transparency? (false by default)
+    /// \return True if loading was successful
+    ///
+    /// \see loadFromFile, loadFromMemory
     ///
     ////////////////////////////////////////////////////////////
-    void Copy(const Image& Source, unsigned int DestX, unsigned int DestY, const IntRect& SourceRect = IntRect(0, 0, 0, 0), bool ApplyAlpha = false);
+    bool loadFromStream(InputStream& stream);
 
     ////////////////////////////////////////////////////////////
-    /// Create the image from the current contents of the
-    /// given window
+    /// \brief Save the image to a file on disk
     ///
-    /// \param Window :     Window to capture
-    /// \param SourceRect : Sub-rectangle of the screen to copy (empty by default - entire image)
+    /// The format of the image is automatically deduced from
+    /// the extension. The supported image formats are bmp, png,
+    /// tga and jpg. The destination file is overwritten
+    /// if it already exists. This function fails if the image is empty.
     ///
-    /// \return True if copy was successful
+    /// \param filename Path of the file to save
     ///
-    ////////////////////////////////////////////////////////////
-    bool CopyScreen(RenderWindow& Window, const IntRect& SourceRect = IntRect(0, 0, 0, 0));
-
-    ////////////////////////////////////////////////////////////
-    /// Change the color of a pixel
+    /// \return True if saving was successful
     ///
-    /// \param X :   X coordinate of pixel in the image
-    /// \param Y :   Y coordinate of pixel in the image
-    /// \param Col : New color for pixel (X, Y)
+    /// \see create, loadFromFile, loadFromMemory
     ///
     ////////////////////////////////////////////////////////////
-    void SetPixel(unsigned int X, unsigned int Y, const Color& Col);
+    bool saveToFile(const std::string& filename) const;
 
     ////////////////////////////////////////////////////////////
-    /// Get a pixel from the image
+    /// \brief Return the size (width and height) of the image
     ///
-    /// \param X : X coordinate of pixel in the image
-    /// \param Y : Y coordinate of pixel in the image
-    ///
-    /// \return Color of pixel (X, Y)
+    /// \return Size of the image, in pixels
     ///
     ////////////////////////////////////////////////////////////
-    const Color& GetPixel(unsigned int X, unsigned int Y) const;
+    Vector2u getSize() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get a read-only pointer to the array of pixels (RGBA 8 bits integers components)
-    /// Array size is GetWidth() x GetHeight() x 4
-    /// This pointer becomes invalid if you reload or resize the image
+    /// \brief Create a transparency mask from a specified color-key
     ///
-    /// \return Const pointer to the array of pixels
+    /// This function sets the alpha value of every pixel matching
+    /// the given color to \a alpha (0 by default), so that they
+    /// become transparent.
     ///
-    ////////////////////////////////////////////////////////////
-    const Uint8* GetPixelsPtr() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Bind the image for rendering
+    /// \param color Color to make transparent
+    /// \param alpha Alpha value to assign to transparent pixels
     ///
     ////////////////////////////////////////////////////////////
-    void Bind() const;
+    void createMaskFromColor(const Color& color, Uint8 alpha = 0);
 
     ////////////////////////////////////////////////////////////
-    /// Enable or disable image smooth filter.
-    /// This parameter is enabled by default
+    /// \brief Copy pixels from another image onto this one
     ///
-    /// \param Smooth : True to enable smoothing filter, false to disable it
+    /// This function does a slow pixel copy and should not be
+    /// used intensively. It can be used to prepare a complex
+    /// static image from several others, but if you need this
+    /// kind of feature in real-time you'd better use sf::RenderTexture.
     ///
-    ////////////////////////////////////////////////////////////
-    void SetSmooth(bool Smooth);
-
-    ////////////////////////////////////////////////////////////
-    /// Return the width of the image
+    /// If \a sourceRect is empty, the whole image is copied.
+    /// If \a applyAlpha is set to true, the transparency of
+    /// source pixels is applied. If it is false, the pixels are
+    /// copied unchanged with their alpha value.
     ///
-    /// \return Width in pixels
+    /// \param source     Source image to copy
+    /// \param destX      X coordinate of the destination position
+    /// \param destY      Y coordinate of the destination position
+    /// \param sourceRect Sub-rectangle of the source image to copy
+    /// \param applyAlpha Should the copy take in account the source transparency?
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetWidth() const;
+    void copy(const Image& source, unsigned int destX, unsigned int destY, const IntRect& sourceRect = IntRect(0, 0, 0, 0), bool applyAlpha = false);
 
     ////////////////////////////////////////////////////////////
-    /// Return the height of the image
+    /// \brief Change the color of a pixel
     ///
-    /// \return Height in pixels
+    /// This function doesn't check the validity of the pixel
+    /// coordinates, using out-of-range values will result in
+    /// an undefined behavior.
     ///
-    ////////////////////////////////////////////////////////////
-    unsigned int GetHeight() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Tells whether the smooth filtering is enabled or not
+    /// \param x     X coordinate of pixel to change
+    /// \param y     Y coordinate of pixel to change
+    /// \param color New color of the pixel
     ///
-    /// \return True if image smoothing is enabled
+    /// \see getPixel
     ///
     ////////////////////////////////////////////////////////////
-    bool IsSmooth() const;
+    void setPixel(unsigned int x, unsigned int y, const Color& color);
 
     ////////////////////////////////////////////////////////////
-    /// Convert a subrect expressed in pixels, into float
-    /// texture coordinates
+    /// \brief Get the color of a pixel
     ///
-    /// \param Rect : Sub-rectangle of image to convert
+    /// This function doesn't check the validity of the pixel
+    /// coordinates, using out-of-range values will result in
+    /// an undefined behavior.
     ///
-    /// \return Texture coordinates corresponding to the sub-rectangle
-    ///
-    ////////////////////////////////////////////////////////////
-    FloatRect GetTexCoords(const IntRect& Rect) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get a valid texture size according to hardware support
+    /// \param x X coordinate of pixel to get
+    /// \param y Y coordinate of pixel to get
     ///
-    /// \param Size : Size to convert
+    /// \return Color of the pixel at coordinates (x, y)
     ///
-    /// \return Valid nearest size (greater than or equal to specified size)
+    /// \see setPixel
     ///
     ////////////////////////////////////////////////////////////
-    static unsigned int GetValidTextureSize(unsigned int Size);
+    Color getPixel(unsigned int x, unsigned int y) const;
 
     ////////////////////////////////////////////////////////////
-    /// Assignment operator
+    /// \brief Get a read-only pointer to the array of pixels
     ///
-    /// \param Other : instance to assign
+    /// The returned value points to an array of RGBA pixels made of
+    /// 8 bits integers components. The size of the array is
+    /// width * height * 4 (getSize().x * getSize().y * 4).
+    /// Warning: the returned pointer may become invalid if you
+    /// modify the image, so you should never store it for too long.
+    /// If the image is empty, a null pointer is returned.
     ///
-    /// \return Reference to the image
+    /// \return Read-only pointer to the array of pixels
     ///
     ////////////////////////////////////////////////////////////
-    Image& operator =(const Image& Other);
-
-private :
+    const Uint8* getPixelsPtr() const;
 
     ////////////////////////////////////////////////////////////
-    /// Create the OpenGL texture
-    ///
-    /// \return True if texture has been successfully created
+    /// \brief Flip the image horizontally (left <-> right)
     ///
     ////////////////////////////////////////////////////////////
-    bool CreateTexture();
-
-    ////////////////////////////////////////////////////////////
-    /// Make sure the texture in video memory is updated with the
-    /// array of pixels
-    ////////////////////////////////////////////////////////////
-    void EnsureTextureUpdate() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Make sure the array of pixels is updated with the
-    /// texture in video memory
-    ////////////////////////////////////////////////////////////
-    void EnsureArrayUpdate() const;
+    void flipHorizontally();
 
     ////////////////////////////////////////////////////////////
-    /// Reset the image attributes
+    /// \brief Flip the image vertically (top <-> bottom)
     ///
     ////////////////////////////////////////////////////////////
-    void Reset();
+    void flipVertically();
 
-    ////////////////////////////////////////////////////////////
-    /// Destroy the OpenGL texture
-    ///
-    ////////////////////////////////////////////////////////////
-    void DestroyTexture();
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    unsigned int               myWidth;             ///< Image width
-    unsigned int               myHeight;            ///< Image Height
-    unsigned int               myTextureWidth;      ///< Actual texture width (can be greater than image width because of padding)
-    unsigned int               myTextureHeight;     ///< Actual texture height (can be greater than image height because of padding)
-    unsigned int               myTexture;           ///< Internal texture identifier
-    bool                       myIsSmooth;          ///< Status of the smooth filter
-    mutable std::vector<Color> myPixels;            ///< Pixels of the image
-    mutable bool               myNeedTextureUpdate; ///< Status of synchronization between pixels in central memory and the internal texture un video memory
-    mutable bool               myNeedArrayUpdate;   ///< Status of synchronization between pixels in central memory and the internal texture un video memory
+    Vector2u           m_size;   ///< Image size
+    std::vector<Uint8> m_pixels; ///< Pixels of the image
+    #ifdef SFML_SYSTEM_ANDROID
+    void*              m_stream; ///< Asset file streamer (if loaded from file)
+    #endif
 };
 
 } // namespace sf
 
 
 #endif // SFML_IMAGE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Image
+/// \ingroup graphics
+///
+/// sf::Image is an abstraction to manipulate images
+/// as bidimensional arrays of pixels. The class provides
+/// functions to load, read, write and save pixels, as well
+/// as many other useful functions.
+///
+/// sf::Image can handle a unique internal representation of
+/// pixels, which is RGBA 32 bits. This means that a pixel
+/// must be composed of 8 bits red, green, blue and alpha
+/// channels -- just like a sf::Color.
+/// All the functions that return an array of pixels follow
+/// this rule, and all parameters that you pass to sf::Image
+/// functions (such as loadFromMemory) must use this
+/// representation as well.
+///
+/// A sf::Image can be copied, but it is a heavy resource and
+/// if possible you should always use [const] references to
+/// pass or return them to avoid useless copies.
+///
+/// Usage example:
+/// \code
+/// // Load an image file from a file
+/// sf::Image background;
+/// if (!background.loadFromFile("background.jpg"))
+///     return -1;
+///
+/// // Create a 20x20 image filled with black color
+/// sf::Image image;
+/// image.create(20, 20, sf::Color::Black);
+///
+/// // Copy image1 on image2 at position (10, 10)
+/// image.copy(background, 10, 10);
+///
+/// // Make the top-left pixel transparent
+/// sf::Color color = image.getPixel(0, 0);
+/// color.a = 0;
+/// image.setPixel(0, 0, color);
+///
+/// // Save the image to a file
+/// if (!image.saveToFile("result.png"))
+///     return -1;
+/// \endcode
+///
+/// \see sf::Texture
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Matrix3.hpp b/dependencies64/sfml/include/SFML/Graphics/Matrix3.hpp
deleted file mode 100644 (file)
index 8103402..0000000
+++ /dev/null
@@ -1,148 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_MATRIX3_HPP
-#define SFML_MATRIX3_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-#include <SFML/System/Vector2.hpp>
-#include <math.h>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// Utility class to manipulate 3x3 matrices representing
-/// 2D transformations
-////////////////////////////////////////////////////////////
-class SFML_API Matrix3
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor (builds an identity matrix)
-    ///
-    ////////////////////////////////////////////////////////////
-    Matrix3();
-
-    ////////////////////////////////////////////////////////////
-    /// Construct a matrix from its 9 elements
-    ///
-    ////////////////////////////////////////////////////////////
-    Matrix3(float a00, float a01, float a02,
-            float a10, float a11, float a12,
-            float a20, float a21, float a22);
-
-    ////////////////////////////////////////////////////////////
-    /// Build a matrix from a set of transformations
-    ///
-    /// \param Center :      Origin for the transformations
-    /// \param Translation : Translation offset
-    /// \param Rotation :    Rotation angle in degrees
-    /// \param Scale :       Scaling factors
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetFromTransformations(const Vector2f& Center, const Vector2f& Translation, float Rotation, const Vector2f& Scale);
-
-    ////////////////////////////////////////////////////////////
-    /// Transform a point by the matrix
-    ///
-    /// \param Point : Point to transform
-    ///
-    /// \return Transformed point
-    ///
-    ////////////////////////////////////////////////////////////
-    Vector2f Transform(const Vector2f& Point) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Return the inverse of the matrix
-    ///
-    /// \return A new matrix which is the inverse of this
-    ///
-    ////////////////////////////////////////////////////////////
-    Matrix3 GetInverse() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Return the elements of the matrix as a 4x4,
-    /// in an array of 16 floats
-    ///
-    /// \return Pointer to the 4x4 matrix elements
-    ///
-    ////////////////////////////////////////////////////////////
-    const float* Get4x4Elements() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Operator () overloads to access the matrix elements
-    ///
-    /// \param Row : Element row (0 based)
-    /// \param Col : Element column (0 based)
-    ///
-    /// \return Matrix element (Row, Col)
-    ///
-    ////////////////////////////////////////////////////////////
-    float  operator ()(unsigned int Row, unsigned int Col) const;
-    float& operator ()(unsigned int Row, unsigned int Col);
-
-    ////////////////////////////////////////////////////////////
-    /// Operator * overload to multiply two matrices
-    ///
-    /// \param Mat : Matrix to multiply
-    ///
-    /// \return this * Mat
-    ///
-    ////////////////////////////////////////////////////////////
-    Matrix3 operator *(const Matrix3& Mat) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Operator *= overload to multiply-assign two matrices
-    ///
-    /// \param Mat : Matrix to multiply
-    ///
-    /// \return this * Mat
-    ///
-    ////////////////////////////////////////////////////////////
-    Matrix3& operator *=(const Matrix3& Mat);
-
-    ////////////////////////////////////////////////////////////
-    // Static member data
-    ////////////////////////////////////////////////////////////
-    static const Matrix3 Identity; ///< Identity matrix
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    float myData[16]; /// Matrix elements (we directly store it as a 4x4 matrix for optimization purpose)
-};
-
-#include <SFML/Graphics/Matrix3.inl>
-
-} // namespace sf
-
-
-#endif // SFML_MATRIX3_HPP
diff --git a/dependencies64/sfml/include/SFML/Graphics/Matrix3.inl b/dependencies64/sfml/include/SFML/Graphics/Matrix3.inl
deleted file mode 100644 (file)
index 6453db3..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFGE - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////
-/// Default constructor (builds an identity matrix)
-////////////////////////////////////////////////////////////
-inline Matrix3::Matrix3()
-{
-    myData[0] = 1.f; myData[4] = 0.f; myData[8]  = 0.f; myData[12] = 0.f;
-    myData[1] = 0.f; myData[5] = 1.f; myData[9]  = 0.f; myData[13] = 0.f;
-    myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
-    myData[3] = 0.f; myData[7] = 0.f; myData[11] = 0.f; myData[15] = 1.f;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Construct a matrix from its 9 elements
-////////////////////////////////////////////////////////////
-inline Matrix3::Matrix3(float a00, float a01, float a02,
-                        float a10, float a11, float a12,
-                        float a20, float a21, float a22)
-{
-    myData[0] = a00; myData[4] = a01; myData[8]  = 0.f; myData[12] = a02;
-    myData[1] = a10; myData[5] = a11; myData[9]  = 0.f; myData[13] = a12;
-    myData[2] = 0.f; myData[6] = 0.f; myData[10] = 1.f; myData[14] = 0.f;
-    myData[3] = a20; myData[7] = a21; myData[11] = 0.f; myData[15] = a22;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Build a matrix from a set of transformations
-////////////////////////////////////////////////////////////
-inline void Matrix3::SetFromTransformations(const Vector2f& Center, const Vector2f& Translation, float Rotation, const Vector2f& Scale)
-{
-    float Angle = Rotation * 3.141592654f / 180.f;
-    float Cos   = static_cast<float>(cos(Angle));
-    float Sin   = static_cast<float>(sin(Angle));
-    float SxCos = Scale.x * Cos;
-    float SyCos = Scale.y * Cos;
-    float SxSin = Scale.x * Sin;
-    float SySin = Scale.y * Sin;
-    float Tx    = -Center.x * SxCos - Center.y * SySin + Translation.x;
-    float Ty    =  Center.x * SxSin - Center.y * SyCos + Translation.y;
-
-    myData[0] =  SxCos; myData[4] = SySin; myData[8]  = 0.f; myData[12] = Tx;
-    myData[1] = -SxSin; myData[5] = SyCos; myData[9]  = 0.f; myData[13] = Ty;
-    myData[2] =  0.f;   myData[6] = 0.f;   myData[10] = 1.f; myData[14] = 0.f;
-    myData[3] =  0.f;   myData[7] = 0.f;   myData[11] = 0.f; myData[15] = 1.f;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Transform a point by the matrix
-////////////////////////////////////////////////////////////
-inline Vector2f Matrix3::Transform(const Vector2f& Point) const
-{
-    return Vector2f(myData[0] * Point.x + myData[4] * Point.y + myData[12],
-                    myData[1] * Point.x + myData[5] * Point.y + myData[13]);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Return the inverse of the matrix
-////////////////////////////////////////////////////////////
-inline Matrix3 Matrix3::GetInverse() const
-{
-    // Compute the determinant
-    float Det = myData[0] * (myData[15] * myData[5] - myData[7] * myData[13]) -
-                myData[1] * (myData[15] * myData[4] - myData[7] * myData[12]) +
-                myData[3] * (myData[13] * myData[4] - myData[5] * myData[12]);
-
-    // Compute the inverse if determinant is not zero
-    if ((Det < -1E-7f) || (Det > 1E-7f))
-    {
-        return Matrix3( (myData[15] * myData[5] - myData[7] * myData[13]) / Det,
-                       -(myData[15] * myData[4] - myData[7] * myData[12]) / Det,
-                        (myData[13] * myData[4] - myData[5] * myData[12]) / Det,
-                       -(myData[15] * myData[1] - myData[3] * myData[13]) / Det,
-                        (myData[15] * myData[0] - myData[3] * myData[12]) / Det,
-                       -(myData[13] * myData[0] - myData[1] * myData[12]) / Det,
-                        (myData[7]  * myData[1] - myData[3] * myData[5])  / Det,
-                       -(myData[7]  * myData[0] - myData[3] * myData[4])  / Det,
-                        (myData[5]  * myData[0] - myData[1] * myData[4])  / Det);
-    }
-    else
-    {
-        return Identity;
-    }
-}
-
-
-////////////////////////////////////////////////////////////
-/// Return the elements of the matrix as a 4x4,
-/// in an array of 16 floats
-////////////////////////////////////////////////////////////
-inline const float* Matrix3::Get4x4Elements() const
-{
-    return myData;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Operator () overloads to access the matrix elements
-////////////////////////////////////////////////////////////
-inline float Matrix3::operator ()(unsigned int Row, unsigned int Col) const
-{
-    switch (Row + Col * 3)
-    {
-        case 0 : return myData[0];
-        case 1 : return myData[1];
-        case 2 : return myData[3];
-        case 3 : return myData[4];
-        case 4 : return myData[5];
-        case 5 : return myData[7];
-        case 6 : return myData[12];
-        case 7 : return myData[13];
-        case 8 : return myData[15];
-
-        default : return myData[0];
-    }
-}
-inline float& Matrix3::operator ()(unsigned int Row, unsigned int Col)
-{
-    switch (Row + Col * 3)
-    {
-        case 0 : return myData[0];
-        case 1 : return myData[1];
-        case 2 : return myData[3];
-        case 3 : return myData[4];
-        case 4 : return myData[5];
-        case 5 : return myData[7];
-        case 6 : return myData[12];
-        case 7 : return myData[13];
-        case 8 : return myData[15];
-
-        default : return myData[0];
-    }
-}
-
-
-////////////////////////////////////////////////////////////
-/// Operator * overload to multiply two matrices
-////////////////////////////////////////////////////////////
-inline Matrix3 Matrix3::operator *(const Matrix3& Mat) const
-{
-    return Matrix3(myData[0] * Mat.myData[0]  + myData[4] * Mat.myData[1]  + myData[12] * Mat.myData[3],
-                   myData[0] * Mat.myData[4]  + myData[4] * Mat.myData[5]  + myData[12] * Mat.myData[7],
-                   myData[0] * Mat.myData[12] + myData[4] * Mat.myData[13] + myData[12] * Mat.myData[15],
-                   myData[1] * Mat.myData[0]  + myData[5] * Mat.myData[1]  + myData[13] * Mat.myData[3],
-                   myData[1] * Mat.myData[4]  + myData[5] * Mat.myData[5]  + myData[13] * Mat.myData[7],
-                   myData[1] * Mat.myData[12] + myData[5] * Mat.myData[13] + myData[13] * Mat.myData[15],
-                   myData[3] * Mat.myData[0]  + myData[7] * Mat.myData[1]  + myData[15] * Mat.myData[3],
-                   myData[3] * Mat.myData[4]  + myData[7] * Mat.myData[5]  + myData[15] * Mat.myData[7],
-                   myData[3] * Mat.myData[12] + myData[7] * Mat.myData[13] + myData[15] * Mat.myData[15]);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Operator *= overload to multiply-assign two matrices
-////////////////////////////////////////////////////////////
-inline Matrix3& Matrix3::operator *=(const Matrix3& Mat)
-{
-    return *this = *this * Mat;
-}
diff --git a/dependencies64/sfml/include/SFML/Graphics/PostFX.hpp b/dependencies64/sfml/include/SFML/Graphics/PostFX.hpp
deleted file mode 100644 (file)
index d0ad21d..0000000
+++ /dev/null
@@ -1,194 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_POSTFX_HPP
-#define SFML_POSTFX_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Graphics/Drawable.hpp>
-#include <SFML/Graphics/Image.hpp>
-#include <istream>
-#include <map>
-#include <string>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// PostFX is used to apply a post effect to a window
-////////////////////////////////////////////////////////////
-class SFML_API PostFX : public Drawable
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    PostFX();
-
-    ////////////////////////////////////////////////////////////
-    /// Copy constructor
-    ///
-    /// \param Copy : Instance to copy
-    ///
-    ////////////////////////////////////////////////////////////
-    PostFX(const PostFX& Copy);
-
-    ////////////////////////////////////////////////////////////
-    /// Destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    ~PostFX();
-
-    ////////////////////////////////////////////////////////////
-    /// Load the effect from a file
-    ///
-    /// \param Filename : Path of the effect file to load
-    ///
-    /// \return True on success
-    ///
-    ////////////////////////////////////////////////////////////
-    bool LoadFromFile(const std::string& Filename);
-
-    ////////////////////////////////////////////////////////////
-    /// Load the effect from a text in memory
-    ///
-    /// \param Effect : String containing the effect code
-    ///
-    /// \return True on success
-    ///
-    ////////////////////////////////////////////////////////////
-    bool LoadFromMemory(const std::string& Effect);
-
-    ////////////////////////////////////////////////////////////
-    /// Change a parameter of the effect (1 float)
-    ///
-    /// \param Name : Parameter name in the effect
-    /// \param X :    Value to assign
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetParameter(const std::string& Name, float X);
-
-    ////////////////////////////////////////////////////////////
-    /// Change a parameter of the effect (2 floats)
-    ///
-    /// \param Name : Parameter name in the effect
-    /// \param X, Y : Values to assign
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetParameter(const std::string& Name, float X, float Y);
-
-    ////////////////////////////////////////////////////////////
-    /// Change a parameter of the effect (3 floats)
-    ///
-    /// \param Name :    Parameter name in the effect
-    /// \param X, Y, Z : Values to assign
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetParameter(const std::string& Name, float X, float Y, float Z);
-
-    ////////////////////////////////////////////////////////////
-    /// Change a parameter of the effect (4 floats)
-    ///
-    /// \param Name :       Parameter name in the effect
-    /// \param X, Y, Z, W : Values to assign
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetParameter(const std::string& Name, float X, float Y, float Z, float W);
-
-    ////////////////////////////////////////////////////////////
-    /// Set a texture parameter
-    ///
-    /// \param Name :    Texture name in the effect
-    /// \param Texture : Image to set (pass NULL to use content of current framebuffer)
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetTexture(const std::string& Name, Image* Texture);
-
-    ////////////////////////////////////////////////////////////
-    /// Assignment operator
-    ///
-    /// \param Other : Instance to assign
-    ///
-    /// \return Reference to the post-effect
-    ///
-    ////////////////////////////////////////////////////////////
-    PostFX& operator =(const PostFX& Other);
-
-    ////////////////////////////////////////////////////////////
-    /// Tell whether or not the system supports post-effects
-    ///
-    /// \return True if the system can use post-effects
-    ///
-    ////////////////////////////////////////////////////////////
-    static bool CanUsePostFX();
-
-protected :
-
-    ////////////////////////////////////////////////////////////
-    /// /see Drawable::Render
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual void Render(RenderTarget& Target) const;
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    /// Preprocess a SFML effect file
-    /// to convert it to a valid GLSL fragment shader
-    ///
-    /// \param File : Stream containing the code to process
-    ///
-    /// \return Valid fragment shader source code
-    ///
-    ////////////////////////////////////////////////////////////
-    static std::string PreprocessEffect(std::istream& File);
-
-    ////////////////////////////////////////////////////////////
-    /// Create the program and attach the shaders
-    ///
-    ////////////////////////////////////////////////////////////
-    void CreateProgram();
-
-    ////////////////////////////////////////////////////////////
-    // Types
-    ////////////////////////////////////////////////////////////
-    typedef std::map<std::string, const Image*> TextureTable;
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    unsigned int  myShaderProgram;  ///< OpenGL identifier for the program
-    TextureTable  myTextures;       ///< Texture variables in the effect
-    std::string   myFragmentShader; ///< Fragment shader source code
-    mutable Image myFrameBuffer;    ///< Texture containing the current frame buffer
-};
-
-} // namespace sf
-
-
-#endif // SFML_POSTFX_HPP
similarity index 50%
rename from dependencies64/sfml/include/SFML/Window/WindowSettings.hpp
rename to dependencies64/sfml/include/SFML/Graphics/PrimitiveType.hpp
index e2e68f7debf53380dc247a950aa67ce64a021c7e..16e7d3594f503d5faeee5aa30c0cd5aacd68cac1 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 //
 ////////////////////////////////////////////////////////////
 
-#ifndef SFML_WINDOWSETTINGS_HPP
-#define SFML_WINDOWSETTINGS_HPP
-
+#ifndef SFML_PRIMITIVETYPE_HPP
+#define SFML_PRIMITIVETYPE_HPP
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Structure defining the creation settings of windows
+/// \ingroup graphics
+/// \brief Types of primitives that a sf::VertexArray can render
+///
+/// Points and lines have no area, therefore their thickness
+/// will always be 1 pixel, regardless the current transform
+/// and view.
+///
 ////////////////////////////////////////////////////////////
-struct WindowSettings
+enum PrimitiveType
 {
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    /// \param Depth :        Depth buffer bits (24 by default)
-    /// \param Stencil :      Stencil buffer bits (8 by default)
-    /// \param Antialiasing : Antialiasing level (0 by default)
-    ///
-    ////////////////////////////////////////////////////////////
-    explicit WindowSettings(unsigned int Depth = 24, unsigned int Stencil = 8, unsigned int Antialiasing = 0) :
-    DepthBits        (Depth),
-    StencilBits      (Stencil),
-    AntialiasingLevel(Antialiasing)
-    {
-    }
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    unsigned int DepthBits;         ///< Bits of the depth buffer
-    unsigned int StencilBits;       ///< Bits of the stencil buffer
-    unsigned int AntialiasingLevel; ///< Level of antialiasing
+    Points,         ///< List of individual points
+    Lines,          ///< List of individual lines
+    LinesStrip,     ///< List of connected lines, a point uses the previous point to form a line
+    Triangles,      ///< List of individual triangles
+    TrianglesStrip, ///< List of connected triangles, a point uses the two previous points to form a triangle
+    TrianglesFan,   ///< List of connected triangles, a point uses the common center and the previous point to form a triangle
+    Quads           ///< List of individual quads (deprecated, don't work with OpenGL ES)
 };
 
 } // namespace sf
 
 
-#endif // SFML_WINDOWSETTINGS_HPP
+#endif // SFML_PRIMITIVETYPE_HPP
index 29432dff36d8453d3fc94a88972dc1231c62cf49..06abfb8eeba718087121ca68361946cbb2449b65 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
+#include <SFML/System/Vector2.hpp>
 #include <algorithm>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Rect is an utility class for manipulating rectangles.
-/// Template parameter defines the type of coordinates (integer, float, ...)
+/// \brief Utility class for manipulating 2D axis aligned rectangles
+///
 ////////////////////////////////////////////////////////////
 template <typename T>
 class Rect
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// Creates an empty rectangle (it is equivalent to calling
+    /// Rect(0, 0, 0, 0)).
     ///
     ////////////////////////////////////////////////////////////
     Rect();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the rectangle from its coordinates
+    /// \brief Construct the rectangle from its coordinates
+    ///
+    /// Be careful, the last two parameters are the width
+    /// and height, not the right and bottom coordinates!
+    ///
+    /// \param rectLeft   Left coordinate of the rectangle
+    /// \param rectTop    Top coordinate of the rectangle
+    /// \param rectWidth  Width of the rectangle
+    /// \param rectHeight Height of the rectangle
+    ///
+    ////////////////////////////////////////////////////////////
+    Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the rectangle from position and size
     ///
-    /// \param LeftCoord :   Left coordinate of the rectangle
-    /// \param TopCoord :    Top coordinate of the rectangle
-    /// \param RightCoord :  Right coordinate of the rectangle
-    /// \param BottomCoord : Bottom coordinate of the rectangle
+    /// Be careful, the last parameter is the size,
+    /// not the bottom-right corner!
+    ///
+    /// \param position Position of the top-left corner of the rectangle
+    /// \param size     Size of the rectangle
     ///
     ////////////////////////////////////////////////////////////
-    Rect(T LeftCoord, T TopCoord, T RightCoord, T BottomCoord);
+    Rect(const Vector2<T>& position, const Vector2<T>& size);
 
     ////////////////////////////////////////////////////////////
-    /// Get the width of the rectangle
+    /// \brief Construct the rectangle from another type of rectangle
+    ///
+    /// This constructor doesn't replace the copy constructor,
+    /// it's called only when U != T.
+    /// A call to this constructor will fail to compile if U
+    /// is not convertible to T.
     ///
-    /// \return Width of rectangle
+    /// \param rectangle Rectangle to convert
     ///
     ////////////////////////////////////////////////////////////
-    T GetWidth() const;
+    template <typename U>
+    explicit Rect(const Rect<U>& rectangle);
 
     ////////////////////////////////////////////////////////////
-    /// Get the height of the rectangle
+    /// \brief Check if a point is inside the rectangle's area
+    ///
+    /// \param x X coordinate of the point to test
+    /// \param y Y coordinate of the point to test
+    ///
+    /// \return True if the point is inside, false otherwise
     ///
-    /// \return Height of rectangle
+    /// \see intersects
     ///
     ////////////////////////////////////////////////////////////
-    T GetHeight() const;
+    bool contains(T x, T y) const;
 
     ////////////////////////////////////////////////////////////
-    /// Move the whole rectangle by the given offset
+    /// \brief Check if a point is inside the rectangle's area
     ///
-    /// \param OffsetX : Horizontal offset
-    /// \param OffsetY : Vertical offset
+    /// \param point Point to test
+    ///
+    /// \return True if the point is inside, false otherwise
+    ///
+    /// \see intersects
     ///
     ////////////////////////////////////////////////////////////
-    void Offset(T OffsetX, T OffsetY);
+    bool contains(const Vector2<T>& point) const;
 
     ////////////////////////////////////////////////////////////
-    /// Check if a point is inside the rectangle's area
+    /// \brief Check the intersection between two rectangles
+    ///
+    /// \param rectangle Rectangle to test
     ///
-    /// \param X : X coordinate of the point to test
-    /// \param Y : Y coordinate of the point to test
+    /// \return True if rectangles overlap, false otherwise
     ///
-    /// \return True if the point is inside
+    /// \see contains
     ///
     ////////////////////////////////////////////////////////////
-    bool Contains(T X, T Y) const;
+    bool intersects(const Rect<T>& rectangle) const;
 
     ////////////////////////////////////////////////////////////
-    /// Check intersection between two rectangles
+    /// \brief Check the intersection between two rectangles
     ///
-    /// \param Rectangle :       Rectangle to test
-    /// \param OverlappingRect : Rectangle to be filled with overlapping rect (NULL by default)
+    /// This overload returns the overlapped rectangle in the
+    /// \a intersection parameter.
     ///
-    /// \return True if rectangles overlap
+    /// \param rectangle    Rectangle to test
+    /// \param intersection Rectangle to be filled with the intersection
+    ///
+    /// \return True if rectangles overlap, false otherwise
+    ///
+    /// \see contains
     ///
     ////////////////////////////////////////////////////////////
-    bool Intersects(const Rect<T>& Rectangle, Rect<T>* OverlappingRect = NULL) const;
+    bool intersects(const Rect<T>& rectangle, Rect<T>& intersection) const;
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    T Left;   ///< Left coordinate of the rectangle
-    T Top;    ///< Top coordinate of the rectangle
-    T Right;  ///< Right coordinate of the rectangle
-    T Bottom; ///< Bottom coordinate of the rectangle
+    T left;   ///< Left coordinate of the rectangle
+    T top;    ///< Top coordinate of the rectangle
+    T width;  ///< Width of the rectangle
+    T height; ///< Height of the rectangle
 };
 
+////////////////////////////////////////////////////////////
+/// \relates Rect
+/// \brief Overload of binary operator ==
+///
+/// This operator compares strict equality between two rectangles.
+///
+/// \param left  Left operand (a rectangle)
+/// \param right Right operand (a rectangle)
+///
+/// \return True if \a left is equal to \a right
+///
+////////////////////////////////////////////////////////////
+template <typename T>
+bool operator ==(const Rect<T>& left, const Rect<T>& right);
+
+////////////////////////////////////////////////////////////
+/// \relates Rect
+/// \brief Overload of binary operator !=
+///
+/// This operator compares strict difference between two rectangles.
+///
+/// \param left  Left operand (a rectangle)
+/// \param right Right operand (a rectangle)
+///
+/// \return True if \a left is not equal to \a right
+///
+////////////////////////////////////////////////////////////
+template <typename T>
+bool operator !=(const Rect<T>& left, const Rect<T>& right);
+
 #include <SFML/Graphics/Rect.inl>
 
-// Define the most common types
+// Create typedefs for the most common types
 typedef Rect<int>   IntRect;
 typedef Rect<float> FloatRect;
 
@@ -125,3 +194,55 @@ typedef Rect<float> FloatRect;
 
 
 #endif // SFML_RECT_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Rect
+/// \ingroup graphics
+///
+/// A rectangle is defined by its top-left corner and its size.
+/// It is a very simple class defined for convenience, so
+/// its member variables (left, top, width and height) are public
+/// and can be accessed directly, just like the vector classes
+/// (Vector2 and Vector3).
+///
+/// To keep things simple, sf::Rect doesn't define
+/// functions to emulate the properties that are not directly
+/// members (such as right, bottom, center, etc.), it rather
+/// only provides intersection functions.
+///
+/// sf::Rect uses the usual rules for its boundaries:
+/// \li The left and top edges are included in the rectangle's area
+/// \li The right (left + width) and bottom (top + height) edges are excluded from the rectangle's area
+///
+/// This means that sf::IntRect(0, 0, 1, 1) and sf::IntRect(1, 1, 1, 1)
+/// don't intersect.
+///
+/// sf::Rect is a template and may be used with any numeric type, but
+/// for simplicity the instantiations used by SFML are typedef'd:
+/// \li sf::Rect<int> is sf::IntRect
+/// \li sf::Rect<float> is sf::FloatRect
+///
+/// So that you don't have to care about the template syntax.
+///
+/// Usage example:
+/// \code
+/// // Define a rectangle, located at (0, 0) with a size of 20x5
+/// sf::IntRect r1(0, 0, 20, 5);
+///
+/// // Define another rectangle, located at (4, 2) with a size of 18x10
+/// sf::Vector2i position(4, 2);
+/// sf::Vector2i size(18, 10);
+/// sf::IntRect r2(position, size);
+///
+/// // Test intersections with the point (3, 1)
+/// bool b1 = r1.contains(3, 1); // true
+/// bool b2 = r2.contains(3, 1); // false
+///
+/// // Test the intersection between r1 and r2
+/// sf::IntRect result;
+/// bool b3 = r1.intersects(r2, result); // true
+/// // result == (4, 2, 16, 3)
+/// \endcode
+///
+////////////////////////////////////////////////////////////
index 970c6dbc5f4cedba579712668bccb8d8779a9e4c..849fc8231f0d0ff6023cb801ebd9541480afce33 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 
 
-////////////////////////////////////////////////////////////
-/// Default constructor
 ////////////////////////////////////////////////////////////
 template <typename T>
 Rect<T>::Rect() :
-Left  (0),
-Top   (0),
-Right (0),
-Bottom(0)
+left  (0),
+top   (0),
+width (0),
+height(0)
 {
 
 }
 
 
-////////////////////////////////////////////////////////////
-/// Construct the color from its coordinates
 ////////////////////////////////////////////////////////////
 template <typename T>
-Rect<T>::Rect(T LeftCoord, T TopCoord, T RightCoord, T BottomCoord) :
-Left  (LeftCoord),
-Top   (TopCoord),
-Right (RightCoord),
-Bottom(BottomCoord)
+Rect<T>::Rect(T rectLeft, T rectTop, T rectWidth, T rectHeight) :
+left  (rectLeft),
+top   (rectTop),
+width (rectWidth),
+height(rectHeight)
 {
 
 }
 
 
-////////////////////////////////////////////////////////////
-/// Get the width of the rectangle
 ////////////////////////////////////////////////////////////
 template <typename T>
-T Rect<T>::GetWidth() const
+Rect<T>::Rect(const Vector2<T>& position, const Vector2<T>& size) :
+left  (position.x),
+top   (position.y),
+width (size.x),
+height(size.y)
 {
-    return Right - Left;
+
 }
 
 
-////////////////////////////////////////////////////////////
-/// Get the height of the rectangle
 ////////////////////////////////////////////////////////////
 template <typename T>
-T Rect<T>::GetHeight() const
+template <typename U>
+Rect<T>::Rect(const Rect<U>& rectangle) :
+left  (static_cast<T>(rectangle.left)),
+top   (static_cast<T>(rectangle.top)),
+width (static_cast<T>(rectangle.width)),
+height(static_cast<T>(rectangle.height))
 {
-    return Bottom - Top;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Move the whole rectangle by the given offset
 ////////////////////////////////////////////////////////////
 template <typename T>
-void Rect<T>::Offset(T OffsetX, T OffsetY)
+bool Rect<T>::contains(T x, T y) const
 {
-    Left   += OffsetX;
-    Right  += OffsetX;
-    Top    += OffsetY;
-    Bottom += OffsetY;
+    // Rectangles with negative dimensions are allowed, so we must handle them correctly
+
+    // Compute the real min and max of the rectangle on both axes
+    T minX = std::min(left, static_cast<T>(left + width));
+    T maxX = std::max(left, static_cast<T>(left + width));
+    T minY = std::min(top, static_cast<T>(top + height));
+    T maxY = std::max(top, static_cast<T>(top + height));
+
+    return (x >= minX) && (x < maxX) && (y >= minY) && (y < maxY);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Check if a point is inside the rectangle's area
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool Rect<T>::Contains(T X, T Y) const
+bool Rect<T>::contains(const Vector2<T>& point) const
 {
-    return (X >= Left) && (X <= Right) && (Y >= Top) && (Y <= Bottom);
+    return contains(point.x, point.y);
 }
 
 
 ////////////////////////////////////////////////////////////
-/// Check intersection between two rectangles
+template <typename T>
+bool Rect<T>::intersects(const Rect<T>& rectangle) const
+{
+    Rect<T> intersection;
+    return intersects(rectangle, intersection);
+}
+
+
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool Rect<T>::Intersects(const Rect<T>& Rectangle, Rect<T>* OverlappingRect) const
+bool Rect<T>::intersects(const Rect<T>& rectangle, Rect<T>& intersection) const
 {
-    // Compute overlapping rect
-    Rect Overlapping(std::max(Left,   Rectangle.Left),
-                     std::max(Top,    Rectangle.Top),
-                     std::min(Right,  Rectangle.Right),
-                     std::min(Bottom, Rectangle.Bottom));
-
-    // If overlapping rect is valid, then there is intersection
-    if ((Overlapping.Left < Overlapping.Right) && (Overlapping.Top < Overlapping.Bottom))
+    // Rectangles with negative dimensions are allowed, so we must handle them correctly
+
+    // Compute the min and max of the first rectangle on both axes
+    T r1MinX = std::min(left, static_cast<T>(left + width));
+    T r1MaxX = std::max(left, static_cast<T>(left + width));
+    T r1MinY = std::min(top, static_cast<T>(top + height));
+    T r1MaxY = std::max(top, static_cast<T>(top + height));
+
+    // Compute the min and max of the second rectangle on both axes
+    T r2MinX = std::min(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
+    T r2MaxX = std::max(rectangle.left, static_cast<T>(rectangle.left + rectangle.width));
+    T r2MinY = std::min(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
+    T r2MaxY = std::max(rectangle.top, static_cast<T>(rectangle.top + rectangle.height));
+
+    // Compute the intersection boundaries
+    T interLeft   = std::max(r1MinX, r2MinX);
+    T interTop    = std::max(r1MinY, r2MinY);
+    T interRight  = std::min(r1MaxX, r2MaxX);
+    T interBottom = std::min(r1MaxY, r2MaxY);
+
+    // If the intersection is valid (positive non zero area), then there is an intersection
+    if ((interLeft < interRight) && (interTop < interBottom))
     {
-        if (OverlappingRect)
-            *OverlappingRect = Overlapping;
+        intersection = Rect<T>(interLeft, interTop, interRight - interLeft, interBottom - interTop);
         return true;
     }
     else
     {
-        if (OverlappingRect)
-            *OverlappingRect = Rect(0, 0, 0, 0);
+        intersection = Rect<T>(0, 0, 0, 0);
         return false;
     }
 }
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+inline bool operator ==(const Rect<T>& left, const Rect<T>& right)
+{
+    return (left.left == right.left) && (left.width == right.width) &&
+           (left.top == right.top) && (left.height == right.height);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+inline bool operator !=(const Rect<T>& left, const Rect<T>& right)
+{
+    return !(left == right);
+}
similarity index 50%
rename from dependencies64/sfml/include/SFML/System/Win32/Thread.hpp
rename to dependencies64/sfml/include/SFML/Graphics/RectangleShape.hpp
index 470dcabd0247109f34e25ade63bc07d68e2fc6bb..8677cc6bd0fac59a5a3c639dcb43f5975f0b19ef 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 //
 ////////////////////////////////////////////////////////////
 
-#ifndef SFML_THREADWIN32_HPP
-#define SFML_THREADWIN32_HPP
+#ifndef SFML_RECTANGLESHAPE_HPP
+#define SFML_RECTANGLESHAPE_HPP
 
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/NonCopyable.hpp>
-#include <windows.h>
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Shape.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Thread defines an easy way to manipulate a thread.
-/// There are two ways to use Thread :
-/// - Inherit from it and override the Run() virtual function
-/// - Construct a Thread instance and pass it a function
-/// pointer to call
+/// \brief Specialized shape representing a rectangle
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Thread : NonCopyable
+class SFML_GRAPHICS_API RectangleShape : public Shape
 {
-public :
-
-    typedef void (*FuncType)(void*);
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Construct the thread from a function pointer
+    /// \brief Default constructor
     ///
-    /// \param Function : Entry point of the thread
-    /// \param UserData : Data to pass to the thread function (NULL by default)
+    /// \param size Size of the rectangle
     ///
     ////////////////////////////////////////////////////////////
-    Thread(FuncType Function, void* UserData = NULL);
+    explicit RectangleShape(const Vector2f& size = Vector2f(0, 0));
 
     ////////////////////////////////////////////////////////////
-    /// Virtual destructor
+    /// \brief Set the size of the rectangle
     ///
-    ////////////////////////////////////////////////////////////
-    virtual ~Thread();
-
-    ////////////////////////////////////////////////////////////
-    /// Create and run the thread
+    /// \param size New size of the rectangle
     ///
-    ////////////////////////////////////////////////////////////
-    void Launch();
-
-    ////////////////////////////////////////////////////////////
-    /// Wait until the thread finishes
+    /// \see getSize
     ///
     ////////////////////////////////////////////////////////////
-    void Wait();
+    void setSize(const Vector2f& size);
 
     ////////////////////////////////////////////////////////////
-    /// Terminate the thread
-    /// Terminating a thread with this function is not safe,
-    /// you should rather try to make the thread function
-    /// terminate by itself
+    /// \brief Get the size of the rectangle
     ///
-    ////////////////////////////////////////////////////////////
-    void Terminate();
-
-protected :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \return Size of the rectangle
+    ///
+    /// \see setSize
     ///
     ////////////////////////////////////////////////////////////
-    Thread();
-
-private :
+    const Vector2f& getSize() const;
 
     ////////////////////////////////////////////////////////////
-    /// Function called as the thread entry point
+    /// \brief Get the number of points defining the shape
+    ///
+    /// \return Number of points of the shape. For rectangle
+    ///         shapes, this number is always 4.
     ///
     ////////////////////////////////////////////////////////////
-    virtual void Run();
+    virtual unsigned int getPointCount() const;
 
     ////////////////////////////////////////////////////////////
-    /// Actual thread entry point, dispatches to instances
+    /// \brief Get a point of the rectangle
+    ///
+    /// The returned point is in local coordinates, that is,
+    /// the shape's transforms (position, rotation, scale) are
+    /// not taken into account.
+    /// The result is undefined if \a index is out of the valid range.
     ///
-    /// \param UserData : Data to pass to the thread function
+    /// \param index Index of the point to get, in range [0 .. 3]
     ///
-    /// \return Error code
+    /// \return index-th point of the shape
     ///
     ////////////////////////////////////////////////////////////
-    static unsigned int __stdcall ThreadFunc(void* UserData);
+    virtual Vector2f getPoint(unsigned int index) const;
+
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    HANDLE   myHandle;   ///< Win32 thread handle
-    FuncType myFunction; ///< Function to call as the thread entry point
-    void*    myUserData; ///< Data to pass to the thread function
+    Vector2f m_size; ///< Size of the rectangle
 };
 
 } // namespace sf
 
 
-#endif // SFML_THREADWIN32_HPP
+#endif // SFML_RECTANGLESHAPE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::RectangleShape
+/// \ingroup graphics
+///
+/// This class inherits all the functions of sf::Transformable
+/// (position, rotation, scale, bounds, ...) as well as the
+/// functions of sf::Shape (outline, color, texture, ...).
+///
+/// Usage example:
+/// \code
+/// sf::RectangleShape rectangle;
+/// rectangle.setSize(sf::Vector2f(100, 50));
+/// rectangle.setOutlineColor(sf::Color::Red);
+/// rectangle.setOutlineThickness(5);
+/// rectangle.setPosition(10, 20);
+/// ...
+/// window.draw(rectangle);
+/// \endcode
+///
+/// \see sf::Shape, sf::CircleShape, sf::ConvexShape
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/RenderStates.hpp b/dependencies64/sfml/include/SFML/Graphics/RenderStates.hpp
new file mode 100644 (file)
index 0000000..2a5ac9a
--- /dev/null
@@ -0,0 +1,174 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_RENDERSTATES_HPP
+#define SFML_RENDERSTATES_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/BlendMode.hpp>
+#include <SFML/Graphics/Transform.hpp>
+
+
+namespace sf
+{
+class Shader;
+class Texture;
+
+////////////////////////////////////////////////////////////
+/// \brief Define the states used for drawing to a RenderTarget
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API RenderStates
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Constructing a default set of render states is equivalent
+    /// to using sf::RenderStates::Default.
+    /// The default set defines:
+    /// \li the BlendAlpha blend mode
+    /// \li the identity transform
+    /// \li a null texture
+    /// \li a null shader
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderStates();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct a default set of render states with a custom blend mode
+    ///
+    /// \param theBlendMode Blend mode to use
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderStates(const BlendMode& theBlendMode);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct a default set of render states with a custom transform
+    ///
+    /// \param theTransform Transform to use
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderStates(const Transform& theTransform);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct a default set of render states with a custom texture
+    ///
+    /// \param theTexture Texture to use
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderStates(const Texture* theTexture);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct a default set of render states with a custom shader
+    ///
+    /// \param theShader Shader to use
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderStates(const Shader* theShader);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct a set of render states with all its attributes
+    ///
+    /// \param theBlendMode Blend mode to use
+    /// \param theTransform Transform to use
+    /// \param theTexture   Texture to use
+    /// \param theShader    Shader to use
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderStates(const BlendMode& theBlendMode, const Transform& theTransform,
+                 const Texture* theTexture, const Shader* theShader);
+
+    ////////////////////////////////////////////////////////////
+    // Static member data
+    ////////////////////////////////////////////////////////////
+    static const RenderStates Default; ///< Special instance holding the default render states
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    BlendMode      blendMode; ///< Blending mode
+    Transform      transform; ///< Transform
+    const Texture* texture;   ///< Texture
+    const Shader*  shader;    ///< Shader
+};
+
+} // namespace sf
+
+
+#endif // SFML_RENDERSTATES_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::RenderStates
+/// \ingroup graphics
+///
+/// There are four global states that can be applied to
+/// the drawn objects:
+/// \li the blend mode: how pixels of the object are blended with the background
+/// \li the transform: how the object is positioned/rotated/scaled
+/// \li the texture: what image is mapped to the object
+/// \li the shader: what custom effect is applied to the object
+///
+/// High-level objects such as sprites or text force some of
+/// these states when they are drawn. For example, a sprite
+/// will set its own texture, so that you don't have to care
+/// about it when drawing the sprite.
+///
+/// The transform is a special case: sprites, texts and shapes
+/// (and it's a good idea to do it with your own drawable classes
+/// too) combine their transform with the one that is passed in the
+/// RenderStates structure. So that you can use a "global" transform
+/// on top of each object's transform.
+///
+/// Most objects, especially high-level drawables, can be drawn
+/// directly without defining render states explicitly -- the
+/// default set of states is ok in most cases.
+/// \code
+/// window.Draw(sprite);
+/// \endcode
+///
+/// If you want to use a single specific render state,
+/// for example a shader, you can pass it directly to the Draw
+/// function: sf::RenderStates has an implicit one-argument
+/// constructor for each state.
+/// \code
+/// window.draw(sprite, shader);
+/// \endcode
+///
+/// When you're inside the Draw function of a drawable
+/// object (inherited from sf::Drawable), you can
+/// either pass the render states unmodified, or change
+/// some of them.
+/// For example, a transformable object will combine the
+/// current transform with its own transform. A sprite will
+/// set its texture. Etc.
+///
+/// \see sf::RenderTarget, sf::Drawable
+///
+////////////////////////////////////////////////////////////
index f7f704949d379485f0473d6d1ead301df8bb928d..01c11e9bf2dba74860c987b98aa94ca073e4834c 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Color.hpp>
-#include <SFML/Graphics/View.hpp>
 #include <SFML/Graphics/Rect.hpp>
+#include <SFML/Graphics/View.hpp>
+#include <SFML/Graphics/Transform.hpp>
+#include <SFML/Graphics/BlendMode.hpp>
+#include <SFML/Graphics/RenderStates.hpp>
+#include <SFML/Graphics/PrimitiveType.hpp>
+#include <SFML/Graphics/Vertex.hpp>
+#include <SFML/System/NonCopyable.hpp>
 
 
 namespace sf
@@ -38,129 +45,407 @@ namespace sf
 class Drawable;
 
 ////////////////////////////////////////////////////////////
-/// Base class for all render targets (window, image, ...)
+/// \brief Base class for all render targets (window, texture, ...)
+///
 ////////////////////////////////////////////////////////////
-class SFML_API RenderTarget
+class SFML_GRAPHICS_API RenderTarget : NonCopyable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
     virtual ~RenderTarget();
 
     ////////////////////////////////////////////////////////////
-    /// Clear the entire target with a single color
+    /// \brief Clear the entire target with a single color
+    ///
+    /// This function is usually called once every frame,
+    /// to clear the previous contents of the target.
+    ///
+    /// \param color Fill color to use to clear the render target
+    ///
+    ////////////////////////////////////////////////////////////
+    void clear(const Color& color = Color(0, 0, 0, 255));
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change the current active view
+    ///
+    /// The view is like a 2D camera, it controls which part of
+    /// the 2D scene is visible, and how it is viewed in the
+    /// render target.
+    /// The new view will affect everything that is drawn, until
+    /// another view is set.
+    /// The render target keeps its own copy of the view object,
+    /// so it is not necessary to keep the original one alive
+    /// after calling this function.
+    /// To restore the original view of the target, you can pass
+    /// the result of getDefaultView() to this function.
+    ///
+    /// \param view New view to use
+    ///
+    /// \see getView, getDefaultView
+    ///
+    ////////////////////////////////////////////////////////////
+    void setView(const View& view);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the view currently in use in the render target
+    ///
+    /// \return The view object that is currently used
+    ///
+    /// \see setView, getDefaultView
+    ///
+    ////////////////////////////////////////////////////////////
+    const View& getView() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the default view of the render target
+    ///
+    /// The default view has the initial size of the render target,
+    /// and never changes after the target has been created.
+    ///
+    /// \return The default view of the render target
+    ///
+    /// \see setView, getView
+    ///
+    ////////////////////////////////////////////////////////////
+    const View& getDefaultView() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the viewport of a view, applied to this render target
+    ///
+    /// The viewport is defined in the view as a ratio, this function
+    /// simply applies this ratio to the current dimensions of the
+    /// render target to calculate the pixels rectangle that the viewport
+    /// actually covers in the target.
+    ///
+    /// \param view The view for which we want to compute the viewport
+    ///
+    /// \return Viewport rectangle, expressed in pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    IntRect getViewport(const View& view) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a point from target coordinates to world
+    ///        coordinates, using the current view
+    ///
+    /// This function is an overload of the mapPixelToCoords
+    /// function that implicitly uses the current view.
+    /// It is equivalent to:
+    /// \code
+    /// target.mapPixelToCoords(point, target.getView());
+    /// \endcode
+    ///
+    /// \param point Pixel to convert
+    ///
+    /// \return The converted point, in "world" coordinates
+    ///
+    /// \see mapCoordsToPixel
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2f mapPixelToCoords(const Vector2i& point) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a point from target coordinates to world coordinates
+    ///
+    /// This function finds the 2D position that matches the
+    /// given pixel of the render target. In other words, it does
+    /// the inverse of what the graphics card does, to find the
+    /// initial position of a rendered pixel.
+    ///
+    /// Initially, both coordinate systems (world units and target pixels)
+    /// match perfectly. But if you define a custom view or resize your
+    /// render target, this assertion is not true anymore, i.e. a point
+    /// located at (10, 50) in your render target may map to the point
+    /// (150, 75) in your 2D world -- if the view is translated by (140, 25).
+    ///
+    /// For render-windows, this function is typically used to find
+    /// which point (or object) is located below the mouse cursor.
+    ///
+    /// This version uses a custom view for calculations, see the other
+    /// overload of the function if you want to use the current view of the
+    /// render target.
+    ///
+    /// \param point Pixel to convert
+    /// \param view The view to use for converting the point
+    ///
+    /// \return The converted point, in "world" units
+    ///
+    /// \see mapCoordsToPixel
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2f mapPixelToCoords(const Vector2i& point, const View& view) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a point from world coordinates to target
+    ///        coordinates, using the current view
+    ///
+    /// This function is an overload of the mapCoordsToPixel
+    /// function that implicitly uses the current view.
+    /// It is equivalent to:
+    /// \code
+    /// target.mapCoordsToPixel(point, target.getView());
+    /// \endcode
+    ///
+    /// \param point Point to convert
     ///
-    /// \param FillColor : Color to use to clear the render target
+    /// \return The converted point, in target coordinates (pixels)
+    ///
+    /// \see mapPixelToCoords
     ///
     ////////////////////////////////////////////////////////////
-    void Clear(const Color& FillColor = Color(0, 0, 0));
+    Vector2i mapCoordsToPixel(const Vector2f& point) const;
 
     ////////////////////////////////////////////////////////////
-    /// Draw something into the target
+    /// \brief Convert a point from world coordinates to target coordinates
+    ///
+    /// This function finds the pixel of the render target that matches
+    /// the given 2D point. In other words, it goes through the same process
+    /// as the graphics card, to compute the final position of a rendered point.
+    ///
+    /// Initially, both coordinate systems (world units and target pixels)
+    /// match perfectly. But if you define a custom view or resize your
+    /// render target, this assertion is not true anymore, i.e. a point
+    /// located at (150, 75) in your 2D world may map to the pixel
+    /// (10, 50) of your render target -- if the view is translated by (140, 25).
+    ///
+    /// This version uses a custom view for calculations, see the other
+    /// overload of the function if you want to use the current view of the
+    /// render target.
+    ///
+    /// \param point Point to convert
+    /// \param view The view to use for converting the point
+    ///
+    /// \return The converted point, in target coordinates (pixels)
     ///
-    /// \param Object : Object to draw
+    /// \see mapPixelToCoords
     ///
     ////////////////////////////////////////////////////////////
-    virtual void Draw(const Drawable& Object);
+    Vector2i mapCoordsToPixel(const Vector2f& point, const View& view) const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the width of the rendering region of the target
+    /// \brief Draw a drawable object to the render target
     ///
-    /// \return Width in pixels
+    /// \param drawable Object to draw
+    /// \param states   Render states to use for drawing
     ///
     ////////////////////////////////////////////////////////////
-    virtual unsigned int GetWidth() const = 0;
+    void draw(const Drawable& drawable, const RenderStates& states = RenderStates::Default);
 
     ////////////////////////////////////////////////////////////
-    /// Get the height of the rendering region of the target
+    /// \brief Draw primitives defined by an array of vertices
     ///
-    /// \return Height in pixels
+    /// \param vertices    Pointer to the vertices
+    /// \param vertexCount Number of vertices in the array
+    /// \param type        Type of primitives to draw
+    /// \param states      Render states to use for drawing
     ///
     ////////////////////////////////////////////////////////////
-    virtual unsigned int GetHeight() const = 0;
+    void draw(const Vertex* vertices, unsigned int vertexCount,
+              PrimitiveType type, const RenderStates& states = RenderStates::Default);
 
     ////////////////////////////////////////////////////////////
-    /// Change the current active view.
+    /// \brief Return the size of the rendering region of the target
     ///
-    /// \param NewView : New view to use (pass GetDefaultView() to set the default view)
+    /// \return Size in pixels
     ///
     ////////////////////////////////////////////////////////////
-    void SetView(const View& NewView);
+    virtual Vector2u getSize() const = 0;
 
     ////////////////////////////////////////////////////////////
-    /// Get the current view
+    /// \brief Save the current OpenGL render states and matrices
     ///
-    /// \return Current view active in the window
+    /// This function can be used when you mix SFML drawing
+    /// and direct OpenGL rendering. Combined with popGLStates,
+    /// it ensures that:
+    /// \li SFML's internal states are not messed up by your OpenGL code
+    /// \li your OpenGL states are not modified by a call to a SFML function
+    ///
+    /// More specifically, it must be used around code that
+    /// calls Draw functions. Example:
+    /// \code
+    /// // OpenGL code here...
+    /// window.pushGLStates();
+    /// window.draw(...);
+    /// window.draw(...);
+    /// window.popGLStates();
+    /// // OpenGL code here...
+    /// \endcode
+    ///
+    /// Note that this function is quite expensive: it saves all the
+    /// possible OpenGL states and matrices, even the ones you
+    /// don't care about. Therefore it should be used wisely.
+    /// It is provided for convenience, but the best results will
+    /// be achieved if you handle OpenGL states yourself (because
+    /// you know which states have really changed, and need to be
+    /// saved and restored). Take a look at the resetGLStates
+    /// function if you do so.
+    ///
+    /// \see popGLStates
     ///
     ////////////////////////////////////////////////////////////
-    const View& GetView() const;
+    void pushGLStates();
 
     ////////////////////////////////////////////////////////////
-    /// Get the default view of the window for read / write
+    /// \brief Restore the previously saved OpenGL render states and matrices
     ///
-    /// \return Default view
+    /// See the description of pushGLStates to get a detailed
+    /// description of these functions.
+    ///
+    /// \see pushGLStates
     ///
     ////////////////////////////////////////////////////////////
-    View& GetDefaultView();
+    void popGLStates();
 
     ////////////////////////////////////////////////////////////
-    /// Tell SFML to preserve external OpenGL states, at the expense of
-    /// more CPU charge. Use this function if you don't want SFML
-    /// to mess up your own OpenGL states (if any).
-    /// Don't enable state preservation if not needed, as it will allow
-    /// SFML to do internal optimizations and improve performances.
-    /// This parameter is false by default
+    /// \brief Reset the internal OpenGL states so that the target is ready for drawing
+    ///
+    /// This function can be used when you mix SFML drawing
+    /// and direct OpenGL rendering, if you choose not to use
+    /// pushGLStates/popGLStates. It makes sure that all OpenGL
+    /// states needed by SFML are set, so that subsequent draw()
+    /// calls will work as expected.
     ///
-    /// \param Preserve : True to preserve OpenGL states, false to let SFML optimize
+    /// Example:
+    /// \code
+    /// // OpenGL code here...
+    /// glPushAttrib(...);
+    /// window.resetGLStates();
+    /// window.draw(...);
+    /// window.draw(...);
+    /// glPopAttrib(...);
+    /// // OpenGL code here...
+    /// \endcode
     ///
     ////////////////////////////////////////////////////////////
-    void PreserveOpenGLStates(bool Preserve);
+    void resetGLStates();
 
-protected :
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
     ///
     ////////////////////////////////////////////////////////////
     RenderTarget();
 
     ////////////////////////////////////////////////////////////
-    /// Called by the derived class when it's ready to be initialized
+    /// \brief Performs the common initialization step after creation
+    ///
+    /// The derived classes must call this function after the
+    /// target is created and ready for drawing.
     ///
     ////////////////////////////////////////////////////////////
-    void Initialize();
+    void initialize();
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
-    /// Activate the target for rendering
+    /// \brief Apply the current view
     ///
-    /// \param Active : True to activate rendering, false to deactivate
+    ////////////////////////////////////////////////////////////
+    void applyCurrentView();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Apply a new blending mode
     ///
-    /// \return True if activation succeeded
+    /// \param mode Blending mode to apply
     ///
     ////////////////////////////////////////////////////////////
-    virtual bool Activate(bool Active) = 0;
+    void applyBlendMode(const BlendMode& mode);
 
     ////////////////////////////////////////////////////////////
-    /// Set the OpenGL render states needed for the SFML rendering
+    /// \brief Apply a new transform
+    ///
+    /// \param transform Transform to apply
     ///
     ////////////////////////////////////////////////////////////
-    void SetRenderStates();
+    void applyTransform(const Transform& transform);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Apply a new texture
+    ///
+    /// \param texture Texture to apply
+    ///
+    ////////////////////////////////////////////////////////////
+    void applyTexture(const Texture* texture);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Apply a new shader
+    ///
+    /// \param shader Shader to apply
+    ///
+    ////////////////////////////////////////////////////////////
+    void applyShader(const Shader* shader);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Activate the target for rendering
+    ///
+    /// This function must be implemented by derived classes to make
+    /// their OpenGL context current; it is called by the base class
+    /// everytime it's going to use OpenGL calls.
+    ///
+    /// \param active True to make the target active, false to deactivate it
+    ///
+    /// \return True if the function succeeded
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool activate(bool active) = 0;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Render states cache
+    ///
+    ////////////////////////////////////////////////////////////
+    struct StatesCache
+    {
+        enum {VertexCacheSize = 4};
+
+        bool      glStatesSet;    ///< Are our internal GL states set yet?
+        bool      viewChanged;    ///< Has the current view changed since last draw?
+        BlendMode lastBlendMode;  ///< Cached blending mode
+        Uint64    lastTextureId;  ///< Cached texture
+        bool      useVertexCache; ///< Did we previously use the vertex cache?
+        Vertex    vertexCache[VertexCacheSize]; ///< Pre-transformed vertices cache
+    };
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    View        myDefaultView;    ///< Default view
-    const View* myCurrentView;    ///< Current active view
-    bool        myPreserveStates; ///< Should we preserve external OpenGL states ?
-    bool        myIsDrawing;      ///< True when Draw is called from inside, to allow some renderstates optimizations
+    View        m_defaultView; ///< Default view
+    View        m_view;        ///< Current view
+    StatesCache m_cache;       ///< Render states cache
 };
 
 } // namespace sf
 
 
 #endif // SFML_RENDERTARGET_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::RenderTarget
+/// \ingroup graphics
+///
+/// sf::RenderTarget defines the common behavior of all the
+/// 2D render targets usable in the graphics module. It makes
+/// it possible to draw 2D entities like sprites, shapes, text
+/// without using any OpenGL command directly.
+///
+/// A sf::RenderTarget is also able to use views (sf::View),
+/// which are a kind of 2D cameras. With views you can globally
+/// scroll, rotate or zoom everything that is drawn,
+/// without having to transform every single entity. See the
+/// documentation of sf::View for more details and sample pieces of
+/// code about this class.
+///
+/// On top of that, render targets are still able to render direct
+/// OpenGL stuff. It is even possible to mix together OpenGL calls
+/// and regular SFML drawing commands. When doing so, make sure that
+/// OpenGL states are not messed up by calling the
+/// pushGLStates/popGLStates functions.
+///
+/// \see sf::RenderWindow, sf::RenderTexture, sf::View
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/RenderTexture.hpp b/dependencies64/sfml/include/SFML/Graphics/RenderTexture.hpp
new file mode 100644 (file)
index 0000000..ff7ae1d
--- /dev/null
@@ -0,0 +1,280 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_RENDERTEXTURE_HPP
+#define SFML_RENDERTEXTURE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Texture.hpp>
+#include <SFML/Graphics/RenderTarget.hpp>
+
+
+namespace sf
+{
+namespace priv
+{
+    class RenderTextureImpl;
+}
+
+////////////////////////////////////////////////////////////
+/// \brief Target for off-screen 2D rendering into a texture
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API RenderTexture : public RenderTarget
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Constructs an empty, invalid render-texture. You must
+    /// call create to have a valid render-texture.
+    ///
+    /// \see create
+    ///
+    ////////////////////////////////////////////////////////////
+    RenderTexture();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~RenderTexture();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create the render-texture
+    ///
+    /// Before calling this function, the render-texture is in
+    /// an invalid state, thus it is mandatory to call it before
+    /// doing anything with the render-texture.
+    /// The last parameter, \a depthBuffer, is useful if you want
+    /// to use the render-texture for 3D OpenGL rendering that requires
+    /// a depth buffer. Otherwise it is unnecessary, and you should
+    /// leave this parameter to false (which is its default value).
+    ///
+    /// \param width       Width of the render-texture
+    /// \param height      Height of the render-texture
+    /// \param depthBuffer Do you want this render-texture to have a depth buffer?
+    ///
+    /// \return True if creation has been successful
+    ///
+    ////////////////////////////////////////////////////////////
+    bool create(unsigned int width, unsigned int height, bool depthBuffer = false);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enable or disable texture smoothing
+    ///
+    /// This function is similar to Texture::setSmooth.
+    /// This parameter is disabled by default.
+    ///
+    /// \param smooth True to enable smoothing, false to disable it
+    ///
+    /// \see isSmooth
+    ///
+    ////////////////////////////////////////////////////////////
+    void setSmooth(bool smooth);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether the smooth filtering is enabled or not
+    ///
+    /// \return True if texture smoothing is enabled
+    ///
+    /// \see setSmooth
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isSmooth() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enable or disable texture repeating
+    ///
+    /// This function is similar to Texture::setRepeated.
+    /// This parameter is disabled by default.
+    ///
+    /// \param repeated True to enable repeating, false to disable it
+    ///
+    /// \see isRepeated
+    ///
+    ////////////////////////////////////////////////////////////
+    void setRepeated(bool repeated);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether the texture is repeated or not
+    ///
+    /// \return True if texture is repeated
+    ///
+    /// \see setRepeated
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isRepeated() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Activate of deactivate the render-texture for rendering
+    ///
+    /// This function makes the render-texture's context current for
+    /// future OpenGL rendering operations (so you shouldn't care
+    /// about it if you're not doing direct OpenGL stuff).
+    /// Only one context can be current in a thread, so if you
+    /// want to draw OpenGL geometry to another render target
+    /// (like a RenderWindow) don't forget to activate it again.
+    ///
+    /// \param active True to activate, false to deactivate
+    ///
+    /// \return True if operation was successful, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    bool setActive(bool active = true);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the contents of the target texture
+    ///
+    /// This function updates the target texture with what
+    /// has been drawn so far. Like for windows, calling this
+    /// function is mandatory at the end of rendering. Not calling
+    /// it may leave the texture in an undefined state.
+    ///
+    ////////////////////////////////////////////////////////////
+    void display();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the size of the rendering region of the texture
+    ///
+    /// The returned value is the size that you passed to
+    /// the create function.
+    ///
+    /// \return Size in pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Vector2u getSize() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a read-only reference to the target texture
+    ///
+    /// After drawing to the render-texture and calling Display,
+    /// you can retrieve the updated texture using this function,
+    /// and draw it using a sprite (for example).
+    /// The internal sf::Texture of a render-texture is always the
+    /// same instance, so that it is possible to call this function
+    /// once and keep a reference to the texture even after it is
+    /// modified.
+    ///
+    /// \return Const reference to the texture
+    ///
+    ////////////////////////////////////////////////////////////
+    const Texture& getTexture() const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Activate the target for rendering
+    ///
+    /// This function is called by the base class
+    /// everytime it's going to use OpenGL calls.
+    ///
+    /// \param active True to make the target active, false to deactivate it
+    ///
+    /// \return True if the function succeeded
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual bool activate(bool active);
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    priv::RenderTextureImpl* m_impl;    ///< Platform/hardware specific implementation
+    Texture                  m_texture; ///< Target texture to draw on
+};
+
+} // namespace sf
+
+
+#endif // SFML_RENDERTEXTURE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::RenderTexture
+/// \ingroup graphics
+///
+/// sf::RenderTexture is the little brother of sf::RenderWindow.
+/// It implements the same 2D drawing and OpenGL-related functions
+/// (see their base class sf::RenderTarget for more details),
+/// the difference is that the result is stored in an off-screen
+/// texture rather than being show in a window.
+///
+/// Rendering to a texture can be useful in a variety of situations:
+/// \li precomputing a complex static texture (like a level's background from multiple tiles)
+/// \li applying post-effects to the whole scene with shaders
+/// \li creating a sprite from a 3D object rendered with OpenGL
+/// \li etc.
+///
+/// Usage example:
+///
+/// \code
+/// // Create a new render-window
+/// sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
+///
+/// // Create a new render-texture
+/// sf::RenderTexture texture;
+/// if (!texture.create(500, 500))
+///     return -1;
+///
+/// // The main loop
+/// while (window.isOpen())
+/// {
+///    // Event processing
+///    // ...
+///
+///    // Clear the whole texture with red color
+///    texture.clear(sf::Color::Red);
+///
+///    // Draw stuff to the texture
+///    texture.draw(sprite);  // sprite is a sf::Sprite
+///    texture.draw(shape);   // shape is a sf::Shape
+///    texture.draw(text);    // text is a sf::Text
+///
+///    // We're done drawing to the texture
+///    texture.display();
+///
+///    // Now we start rendering to the window, clear it first
+///    window.clear();
+///
+///    // Draw the texture
+///    sf::Sprite sprite(texture.getTexture());
+///    window.draw(sprite);
+///
+///    // End the current frame and display its contents on screen
+///    window.display();
+/// }
+/// \endcode
+///
+/// Like sf::RenderWindow, sf::RenderTexture is still able to render direct
+/// OpenGL stuff. It is even possible to mix together OpenGL calls
+/// and regular SFML drawing commands. If you need a depth buffer for
+/// 3D rendering, don't forget to request it when calling RenderTexture::create.
+///
+/// \see sf::RenderTarget, sf::RenderWindow, sf::View, sf::Texture
+///
+////////////////////////////////////////////////////////////
index 2ee44a05a89b07a7a1532d855d240add534598f1..5ff4a6874476eb7fae1a341024426f91a1437ba7 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Graphics/Image.hpp>
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/RenderTarget.hpp>
+#include <SFML/Graphics/Image.hpp>
 #include <SFML/Window/Window.hpp>
 #include <string>
 
 
 namespace sf
 {
-class Drawable;
-
 ////////////////////////////////////////////////////////////
-/// Simple wrapper for sf::Window that allows easy
-/// 2D rendering
+/// \brief Window that can serve as a target for 2D drawing
+///
 ////////////////////////////////////////////////////////////
-class SFML_API RenderWindow : public Window, public RenderTarget
+class SFML_GRAPHICS_API RenderWindow : public Window, public RenderTarget
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// This constructor doesn't actually create the window,
+    /// use the other constructors or call create() to do so.
     ///
     ////////////////////////////////////////////////////////////
     RenderWindow();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the window
+    /// \brief Construct a new window
+    ///
+    /// This constructor creates the window with the size and pixel
+    /// depth defined in \a mode. An optional style can be passed to
+    /// customize the look and behavior of the window (borders,
+    /// title bar, resizable, closable, ...).
+    ///
+    /// The fourth parameter is an optional structure specifying
+    /// advanced OpenGL context settings such as antialiasing,
+    /// depth-buffer bits, etc. You shouldn't care about these
+    /// parameters for a regular usage of the graphics module.
     ///
-    /// \param Mode :        Video mode to use
-    /// \param Title :       Title of the window
-    /// \param WindowStyle : Window style, see sf::Style (Resize | Close by default)
-    /// \param Params :      Creation parameters (see default constructor for default values)
+    /// \param mode     Video mode to use (defines the width, height and depth of the rendering area of the window)
+    /// \param title    Title of the window
+    /// \param style    %Window style, a bitwise OR combination of sf::Style enumerators
+    /// \param settings Additional settings for the underlying OpenGL context
     ///
     ////////////////////////////////////////////////////////////
-    RenderWindow(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings());
+    RenderWindow(VideoMode mode, const String& title, Uint32 style = Style::Default, const ContextSettings& settings = ContextSettings());
 
     ////////////////////////////////////////////////////////////
-    /// Construct the window from an existing control
+    /// \brief Construct the window from an existing control
     ///
-    /// \param Handle : Platform-specific handle of the control
-    /// \param Params : Creation parameters (see default constructor for default values)
+    /// Use this constructor if you want to create an SFML
+    /// rendering area into an already existing control.
+    ///
+    /// The second parameter is an optional structure specifying
+    /// advanced OpenGL context settings such as antialiasing,
+    /// depth-buffer bits, etc. You shouldn't care about these
+    /// parameters for a regular usage of the graphics module.
+    ///
+    /// \param handle   Platform-specific handle of the control (\a HWND on
+    ///                 Windows, \a %Window on Linux/FreeBSD, \a NSWindow on OS X)
+    /// \param settings Additional settings for the underlying OpenGL context
     ///
     ////////////////////////////////////////////////////////////
-    RenderWindow(WindowHandle Handle, const WindowSettings& Params = WindowSettings());
+    explicit RenderWindow(WindowHandle handle, const ContextSettings& settings = ContextSettings());
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Destructor
+    ///
+    /// Closes the window and frees all the resources attached to it.
     ///
     ////////////////////////////////////////////////////////////
     virtual ~RenderWindow();
 
     ////////////////////////////////////////////////////////////
-    /// Get the width of the rendering region of the window
+    /// \brief Get the size of the rendering region of the window
     ///
-    /// \return Width in pixels
+    /// The size doesn't include the titlebar and borders
+    /// of the window.
+    ///
+    /// \return Size in pixels
     ///
     ////////////////////////////////////////////////////////////
-    virtual unsigned int GetWidth() const;
+    virtual Vector2u getSize() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the height of the rendering region of the window
+    /// \brief Copy the current contents of the window to an image
+    ///
+    /// This is a slow operation, whose main purpose is to make
+    /// screenshots of the application. If you want to update an
+    /// image with the contents of the window and then use it for
+    /// drawing, you should rather use a sf::Texture and its
+    /// update(Window&) function.
+    /// You can also draw things directly to a texture with the
+    /// sf::RenderTexture class.
     ///
-    /// \return Height in pixels
+    /// \return Image containing the captured contents
     ///
     ////////////////////////////////////////////////////////////
-    virtual unsigned int GetHeight() const;
+    Image capture() const;
+
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// Save the content of the window to an image
+    /// \brief Function called after the window has been created
     ///
-    /// \return Image instance containing the contents of the screen
+    /// This function is called so that derived classes can
+    /// perform their own specific initialization as soon as
+    /// the window is created.
     ///
     ////////////////////////////////////////////////////////////
-    Image Capture() const;
+    virtual void onCreate();
 
     ////////////////////////////////////////////////////////////
-    /// Convert a point in window coordinates into view coordinates
-    ///
-    /// \param WindowX :    X coordinate of the point to convert, relative to the window
-    /// \param WindowY :    Y coordinate of the point to convert, relative to the window
-    /// \param TargetView : Target view to convert the point to (NULL by default -- uses the current view)
+    /// \brief Function called after the window has been resized
     ///
-    /// \return Converted point
+    /// This function is called so that derived classes can
+    /// perform custom actions when the size of the window changes.
     ///
     ////////////////////////////////////////////////////////////
-    sf::Vector2f ConvertCoords(unsigned int WindowX, unsigned int WindowY, const View* TargetView = NULL) const;
+    virtual void onResize();
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
-    /// /see Window::OnCreate
+    /// \brief Activate the target for rendering
     ///
-    ////////////////////////////////////////////////////////////
-    virtual void OnCreate();
-
-    ////////////////////////////////////////////////////////////
-    /// /see RenderTarget::Activate
+    /// \param active True to make the target active, false to deactivate it
+    ///
+    /// \return True if the function succeeded
     ///
     ////////////////////////////////////////////////////////////
-    virtual bool Activate(bool Active);
+    virtual bool activate(bool active);
 };
 
 } // namespace sf
 
 
 #endif // SFML_RENDERWINDOW_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::RenderWindow
+/// \ingroup graphics
+///
+/// sf::RenderWindow is the main class of the Graphics module.
+/// It defines an OS window that can be painted using the other
+/// classes of the graphics module.
+///
+/// sf::RenderWindow is derived from sf::Window, thus it inherits
+/// all its features: events, window management, OpenGL rendering,
+/// etc. See the documentation of sf::Window for a more complete
+/// description of all these features, as well as code examples.
+///
+/// On top of that, sf::RenderWindow adds more features related to
+/// 2D drawing with the graphics module (see its base class
+/// sf::RenderTarget for more details).
+/// Here is a typical rendering and event loop with a sf::RenderWindow:
+///
+/// \code
+/// // Declare and create a new render-window
+/// sf::RenderWindow window(sf::VideoMode(800, 600), "SFML window");
+///
+/// // Limit the framerate to 60 frames per second (this step is optional)
+/// window.setFramerateLimit(60);
+///
+/// // The main loop - ends as soon as the window is closed
+/// while (window.isOpen())
+/// {
+///    // Event processing
+///    sf::Event event;
+///    while (window.pollEvent(event))
+///    {
+///        // Request for closing the window
+///        if (event.type == sf::Event::Closed)
+///            window.close();
+///    }
+///
+///    // Clear the whole window before rendering a new frame
+///    window.clear();
+///
+///    // Draw some graphical entities
+///    window.draw(sprite);
+///    window.draw(circle);
+///    window.draw(text);
+///
+///    // End the current frame and display its contents on screen
+///    window.display();
+/// }
+/// \endcode
+///
+/// Like sf::Window, sf::RenderWindow is still able to render direct
+/// OpenGL stuff. It is even possible to mix together OpenGL calls
+/// and regular SFML drawing commands.
+///
+/// \code
+/// // Create the render window
+/// sf::RenderWindow window(sf::VideoMode(800, 600), "SFML OpenGL");
+///
+/// // Create a sprite and a text to display
+/// sf::Sprite sprite;
+/// sf::Text text;
+/// ...
+///
+/// // Perform OpenGL initializations
+/// glMatrixMode(GL_PROJECTION);
+/// ...
+///
+/// // Start the rendering loop
+/// while (window.isOpen())
+/// {
+///     // Process events
+///     ...
+///
+///     // Draw a background sprite
+///     window.pushGLStates();
+///     window.draw(sprite);
+///     window.popGLStates();
+///
+///     // Draw a 3D object using OpenGL
+///     glBegin(GL_QUADS);
+///         glVertex3f(...);
+///         ...
+///     glEnd();
+///
+///     // Draw text on top of the 3D object
+///     window.pushGLStates();
+///     window.draw(text);
+///     window.popGLStates();
+///
+///     // Finally, display the rendered frame on screen
+///     window.display();
+/// }
+/// \endcode
+///
+/// \see sf::Window, sf::RenderTarget, sf::RenderTexture, sf::View
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Shader.hpp b/dependencies64/sfml/include/SFML/Graphics/Shader.hpp
new file mode 100644 (file)
index 0000000..c60db27
--- /dev/null
@@ -0,0 +1,647 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SHADER_HPP
+#define SFML_SHADER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Transform.hpp>
+#include <SFML/Graphics/Color.hpp>
+#include <SFML/Window/GlResource.hpp>
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/System/Vector2.hpp>
+#include <SFML/System/Vector3.hpp>
+#include <map>
+#include <string>
+
+
+namespace sf
+{
+class InputStream;
+class Texture;
+
+////////////////////////////////////////////////////////////
+/// \brief Shader class (vertex and fragment)
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API Shader : GlResource, NonCopyable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Types of shaders
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Type
+    {
+        Vertex,  ///< Vertex shader
+        Fragment ///< Fragment (pixel) shader
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Special type that can be passed to setParameter,
+    ///        and that represents the texture of the object being drawn
+    ///
+    /// \see setParameter(const std::string&, CurrentTextureType)
+    ///
+    ////////////////////////////////////////////////////////////
+    struct CurrentTextureType {};
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Represents the texture of the object being drawn
+    ///
+    /// \see setParameter(const std::string&, CurrentTextureType)
+    ///
+    ////////////////////////////////////////////////////////////
+    static CurrentTextureType CurrentTexture;
+
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor creates an invalid shader.
+    ///
+    ////////////////////////////////////////////////////////////
+    Shader();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    ~Shader();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load either the vertex or fragment shader from a file
+    ///
+    /// This function loads a single shader, either vertex or
+    /// fragment, identified by the second argument.
+    /// The source must be a text file containing a valid
+    /// shader in GLSL language. GLSL is a C-like language
+    /// dedicated to OpenGL shaders; you'll probably need to
+    /// read a good documentation for it before writing your
+    /// own shaders.
+    ///
+    /// \param filename Path of the vertex or fragment shader file to load
+    /// \param type     Type of shader (vertex or fragment)
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromMemory, loadFromStream
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromFile(const std::string& filename, Type type);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load both the vertex and fragment shaders from files
+    ///
+    /// This function loads both the vertex and the fragment
+    /// shaders. If one of them fails to load, the shader is left
+    /// empty (the valid shader is unloaded).
+    /// The sources must be text files containing valid shaders
+    /// in GLSL language. GLSL is a C-like language dedicated to
+    /// OpenGL shaders; you'll probably need to read a good documentation
+    /// for it before writing your own shaders.
+    ///
+    /// \param vertexShaderFilename   Path of the vertex shader file to load
+    /// \param fragmentShaderFilename Path of the fragment shader file to load
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromMemory, loadFromStream
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromFile(const std::string& vertexShaderFilename, const std::string& fragmentShaderFilename);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load either the vertex or fragment shader from a source code in memory
+    ///
+    /// This function loads a single shader, either vertex or
+    /// fragment, identified by the second argument.
+    /// The source code must be a valid shader in GLSL language.
+    /// GLSL is a C-like language dedicated to OpenGL shaders;
+    /// you'll probably need to read a good documentation for
+    /// it before writing your own shaders.
+    ///
+    /// \param shader String containing the source code of the shader
+    /// \param type   Type of shader (vertex or fragment)
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromStream
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromMemory(const std::string& shader, Type type);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load both the vertex and fragment shaders from source codes in memory
+    ///
+    /// This function loads both the vertex and the fragment
+    /// shaders. If one of them fails to load, the shader is left
+    /// empty (the valid shader is unloaded).
+    /// The sources must be valid shaders in GLSL language. GLSL is
+    /// a C-like language dedicated to OpenGL shaders; you'll
+    /// probably need to read a good documentation for it before
+    /// writing your own shaders.
+    ///
+    /// \param vertexShader   String containing the source code of the vertex shader
+    /// \param fragmentShader String containing the source code of the fragment shader
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromStream
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromMemory(const std::string& vertexShader, const std::string& fragmentShader);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load either the vertex or fragment shader from a custom stream
+    ///
+    /// This function loads a single shader, either vertex or
+    /// fragment, identified by the second argument.
+    /// The source code must be a valid shader in GLSL language.
+    /// GLSL is a C-like language dedicated to OpenGL shaders;
+    /// you'll probably need to read a good documentation for it
+    /// before writing your own shaders.
+    ///
+    /// \param stream Source stream to read from
+    /// \param type   Type of shader (vertex or fragment)
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromMemory
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromStream(InputStream& stream, Type type);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load both the vertex and fragment shaders from custom streams
+    ///
+    /// This function loads both the vertex and the fragment
+    /// shaders. If one of them fails to load, the shader is left
+    /// empty (the valid shader is unloaded).
+    /// The source codes must be valid shaders in GLSL language.
+    /// GLSL is a C-like language dedicated to OpenGL shaders;
+    /// you'll probably need to read a good documentation for
+    /// it before writing your own shaders.
+    ///
+    /// \param vertexShaderStream   Source stream to read the vertex shader from
+    /// \param fragmentShaderStream Source stream to read the fragment shader from
+    ///
+    /// \return True if loading succeeded, false if it failed
+    ///
+    /// \see loadFromFile, loadFromMemory
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromStream(InputStream& vertexShaderStream, InputStream& fragmentShaderStream);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a float parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a float
+    /// (float GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform float myparam; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("myparam", 5.2f);
+    /// \endcode
+    ///
+    /// \param name Name of the parameter in the shader
+    /// \param x    Value to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, float x);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a 2-components vector parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 2x1 vector
+    /// (vec2 GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform vec2 myparam; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("myparam", 5.2f, 6.0f);
+    /// \endcode
+    ///
+    /// \param name Name of the parameter in the shader
+    /// \param x    First component of the value to assign
+    /// \param y    Second component of the value to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, float x, float y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a 3-components vector parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 3x1 vector
+    /// (vec3 GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform vec3 myparam; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("myparam", 5.2f, 6.0f, -8.1f);
+    /// \endcode
+    ///
+    /// \param name Name of the parameter in the shader
+    /// \param x    First component of the value to assign
+    /// \param y    Second component of the value to assign
+    /// \param z    Third component of the value to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, float x, float y, float z);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a 4-components vector parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 4x1 vector
+    /// (vec4 GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform vec4 myparam; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("myparam", 5.2f, 6.0f, -8.1f, 0.4f);
+    /// \endcode
+    ///
+    /// \param name Name of the parameter in the shader
+    /// \param x    First component of the value to assign
+    /// \param y    Second component of the value to assign
+    /// \param z    Third component of the value to assign
+    /// \param w    Fourth component of the value to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, float x, float y, float z, float w);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a 2-components vector parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 2x1 vector
+    /// (vec2 GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform vec2 myparam; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("myparam", sf::Vector2f(5.2f, 6.0f));
+    /// \endcode
+    ///
+    /// \param name   Name of the parameter in the shader
+    /// \param vector Vector to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, const Vector2f& vector);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a 3-components vector parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 3x1 vector
+    /// (vec3 GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform vec3 myparam; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("myparam", sf::Vector3f(5.2f, 6.0f, -8.1f));
+    /// \endcode
+    ///
+    /// \param name   Name of the parameter in the shader
+    /// \param vector Vector to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, const Vector3f& vector);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a color parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 4x1 vector
+    /// (vec4 GLSL type).
+    ///
+    /// It is important to note that the components of the color are
+    /// normalized before being passed to the shader. Therefore,
+    /// they are converted from range [0 .. 255] to range [0 .. 1].
+    /// For example, a sf::Color(255, 125, 0, 255) will be transformed
+    /// to a vec4(1.0, 0.5, 0.0, 1.0) in the shader.
+    ///
+    /// Example:
+    /// \code
+    /// uniform vec4 color; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("color", sf::Color(255, 128, 0, 255));
+    /// \endcode
+    ///
+    /// \param name  Name of the parameter in the shader
+    /// \param color Color to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, const Color& color);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a matrix parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 4x4 matrix
+    /// (mat4 GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform mat4 matrix; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// sf::Transform transform;
+    /// transform.translate(5, 10);
+    /// shader.setParameter("matrix", transform);
+    /// \endcode
+    ///
+    /// \param name      Name of the parameter in the shader
+    /// \param transform Transform to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, const sf::Transform& transform);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a texture parameter of the shader
+    ///
+    /// \a name is the name of the variable to change in the shader.
+    /// The corresponding parameter in the shader must be a 2D texture
+    /// (sampler2D GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform sampler2D the_texture; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// sf::Texture texture;
+    /// ...
+    /// shader.setParameter("the_texture", texture);
+    /// \endcode
+    /// It is important to note that \a texture must remain alive as long
+    /// as the shader uses it, no copy is made internally.
+    ///
+    /// To use the texture of the object being draw, which cannot be
+    /// known in advance, you can pass the special value
+    /// sf::Shader::CurrentTexture:
+    /// \code
+    /// shader.setParameter("the_texture", sf::Shader::CurrentTexture).
+    /// \endcode
+    ///
+    /// \param name    Name of the texture in the shader
+    /// \param texture Texture to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, const Texture& texture);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change a texture parameter of the shader
+    ///
+    /// This overload maps a shader texture variable to the
+    /// texture of the object being drawn, which cannot be
+    /// known in advance. The second argument must be
+    /// sf::Shader::CurrentTexture.
+    /// The corresponding parameter in the shader must be a 2D texture
+    /// (sampler2D GLSL type).
+    ///
+    /// Example:
+    /// \code
+    /// uniform sampler2D current; // this is the variable in the shader
+    /// \endcode
+    /// \code
+    /// shader.setParameter("current", sf::Shader::CurrentTexture);
+    /// \endcode
+    ///
+    /// \param name Name of the texture in the shader
+    ///
+    ////////////////////////////////////////////////////////////
+    void setParameter(const std::string& name, CurrentTextureType);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Bind a shader for rendering
+    ///
+    /// This function is not part of the graphics API, it mustn't be
+    /// used when drawing SFML entities. It must be used only if you
+    /// mix sf::Shader with OpenGL code.
+    ///
+    /// \code
+    /// sf::Shader s1, s2;
+    /// ...
+    /// sf::Shader::bind(&s1);
+    /// // draw OpenGL stuff that use s1...
+    /// sf::Shader::bind(&s2);
+    /// // draw OpenGL stuff that use s2...
+    /// sf::Shader::bind(NULL);
+    /// // draw OpenGL stuff that use no shader...
+    /// \endcode
+    ///
+    /// \param shader Shader to bind, can be null to use no shader
+    ///
+    ////////////////////////////////////////////////////////////
+    static void bind(const Shader* shader);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether or not the system supports shaders
+    ///
+    /// This function should always be called before using
+    /// the shader features. If it returns false, then
+    /// any attempt to use sf::Shader will fail.
+    ///
+    /// Note: The first call to this function, whether by your
+    /// code or SFML will result in a context switch.
+    ///
+    /// \return True if shaders are supported, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isAvailable();
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Compile the shader(s) and create the program
+    ///
+    /// If one of the arguments is NULL, the corresponding shader
+    /// is not created.
+    ///
+    /// \param vertexShaderCode   Source code of the vertex shader
+    /// \param fragmentShaderCode Source code of the fragment shader
+    ///
+    /// \return True on success, false if any error happened
+    ///
+    ////////////////////////////////////////////////////////////
+    bool compile(const char* vertexShaderCode, const char* fragmentShaderCode);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Bind all the textures used by the shader
+    ///
+    /// This function each texture to a different unit, and
+    /// updates the corresponding variables in the shader accordingly.
+    ///
+    ////////////////////////////////////////////////////////////
+    void bindTextures() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the location ID of a shader parameter
+    ///
+    /// \param name Name of the parameter to search
+    ///
+    /// \return Location ID of the parameter, or -1 if not found
+    ///
+    ////////////////////////////////////////////////////////////
+    int getParamLocation(const std::string& name);
+
+    ////////////////////////////////////////////////////////////
+    // Types
+    ////////////////////////////////////////////////////////////
+    typedef std::map<int, const Texture*> TextureTable;
+    typedef std::map<std::string, int> ParamTable;
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    unsigned int m_shaderProgram;  ///< OpenGL identifier for the program
+    int          m_currentTexture; ///< Location of the current texture in the shader
+    TextureTable m_textures;       ///< Texture variables in the shader, mapped to their location
+    ParamTable   m_params;         ///< Parameters location cache
+};
+
+} // namespace sf
+
+
+#endif // SFML_SHADER_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Shader
+/// \ingroup graphics
+///
+/// Shaders are programs written using a specific language,
+/// executed directly by the graphics card and allowing
+/// to apply real-time operations to the rendered entities.
+///
+/// There are two kinds of shaders:
+/// \li Vertex shaders, that process vertices
+/// \li Fragment (pixel) shaders, that process pixels
+///
+/// A sf::Shader can be composed of either a vertex shader
+/// alone, a fragment shader alone, or both combined
+/// (see the variants of the load functions).
+///
+/// Shaders are written in GLSL, which is a C-like
+/// language dedicated to OpenGL shaders. You'll probably
+/// need to learn its basics before writing your own shaders
+/// for SFML.
+///
+/// Like any C/C++ program, a shader has its own variables
+/// that you can set from your C++ application. sf::Shader
+/// handles 5 different types of variables:
+/// \li floats
+/// \li vectors (2, 3 or 4 components)
+/// \li colors
+/// \li textures
+/// \li transforms (matrices)
+///
+/// The value of the variables can be changed at any time
+/// with the various overloads of the setParameter function:
+/// \code
+/// shader.setParameter("offset", 2.f);
+/// shader.setParameter("point", 0.5f, 0.8f, 0.3f);
+/// shader.setParameter("color", sf::Color(128, 50, 255));
+/// shader.setParameter("matrix", transform); // transform is a sf::Transform
+/// shader.setParameter("overlay", texture); // texture is a sf::Texture
+/// shader.setParameter("texture", sf::Shader::CurrentTexture);
+/// \endcode
+///
+/// The special Shader::CurrentTexture argument maps the
+/// given texture variable to the current texture of the
+/// object being drawn (which cannot be known in advance).
+///
+/// To apply a shader to a drawable, you must pass it as an
+/// additional parameter to the Draw function:
+/// \code
+/// window.draw(sprite, &shader);
+/// \endcode
+///
+/// ... which is in fact just a shortcut for this:
+/// \code
+/// sf::RenderStates states;
+/// states.shader = &shader;
+/// window.draw(sprite, states);
+/// \endcode
+///
+/// In the code above we pass a pointer to the shader, because it may
+/// be null (which means "no shader").
+///
+/// Shaders can be used on any drawable, but some combinations are
+/// not interesting. For example, using a vertex shader on a sf::Sprite
+/// is limited because there are only 4 vertices, the sprite would
+/// have to be subdivided in order to apply wave effects.
+/// Another bad example is a fragment shader with sf::Text: the texture
+/// of the text is not the actual text that you see on screen, it is
+/// a big texture containing all the characters of the font in an
+/// arbitrary order; thus, texture lookups on pixels other than the
+/// current one may not give you the expected result.
+///
+/// Shaders can also be used to apply global post-effects to the
+/// current contents of the target (like the old sf::PostFx class
+/// in SFML 1). This can be done in two different ways:
+/// \li draw everything to a sf::RenderTexture, then draw it to
+///     the main target using the shader
+/// \li draw everything directly to the main target, then use
+///     sf::Texture::update(Window&) to copy its contents to a texture
+///     and draw it to the main target using the shader
+///
+/// The first technique is more optimized because it doesn't involve
+/// retrieving the target's pixels to system memory, but the
+/// second one doesn't impact the rendering process and can be
+/// easily inserted anywhere without impacting all the code.
+///
+/// Like sf::Texture that can be used as a raw OpenGL texture,
+/// sf::Shader can also be used directly as a raw shader for
+/// custom OpenGL geometry.
+/// \code
+/// sf::Shader::bind(&shader);
+/// ... render OpenGL geometry ...
+/// sf::Shader::bind(NULL);
+/// \endcode
+///
+////////////////////////////////////////////////////////////
index 3d541435f336450986ae0b8886c995c2a88af611..fd5491c937488ad8df5e17ec40e8da4d3462d4bd 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Drawable.hpp>
+#include <SFML/Graphics/Transformable.hpp>
+#include <SFML/Graphics/VertexArray.hpp>
 #include <SFML/System/Vector2.hpp>
-#include <vector>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Shape defines a drawable convex shape ; it also defines
-/// helper functions to draw simple shapes like
-/// lines, rectangles, circles, etc.
+/// \brief Base class for textured shapes with outline
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Shape : public sf::Drawable
+class SFML_GRAPHICS_API Shape : public Drawable, public Transformable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Virtual destructor
     ///
     ////////////////////////////////////////////////////////////
-    Shape();
+    virtual ~Shape();
 
     ////////////////////////////////////////////////////////////
-    /// Add a point to the shape
+    /// \brief Change the source texture of the shape
     ///
-    /// \param X, Y :       Position of the point
-    /// \param Col :        Color of the point (white by default)
-    /// \param OutlineCol : Outline color of the point (black by default)
+    /// The \a texture argument refers to a texture that must
+    /// exist as long as the shape uses it. Indeed, the shape
+    /// doesn't store its own copy of the texture, but rather keeps
+    /// a pointer to the one that you passed to this function.
+    /// If the source texture is destroyed and the shape tries to
+    /// use it, the behavior is undefined.
+    /// \a texture can be NULL to disable texturing.
+    /// If \a resetRect is true, the TextureRect property of
+    /// the shape is automatically adjusted to the size of the new
+    /// texture. If it is false, the texture rect is left unchanged.
     ///
-    ////////////////////////////////////////////////////////////
-    void AddPoint(float X, float Y, const Color& Col = Color(255, 255, 255), const Color& OutlineCol = Color(0, 0, 0));
-
-    ////////////////////////////////////////////////////////////
-    /// Add a point to the shape
+    /// \param texture   New texture
+    /// \param resetRect Should the texture rect be reset to the size of the new texture?
     ///
-    /// \param Position :   Position of the point
-    /// \param Col :        Color of the point (white by default)
-    /// \param OutlineCol : Outline color of the point (black by default)
+    /// \see getTexture, setTextureRect
     ///
     ////////////////////////////////////////////////////////////
-    void AddPoint(const Vector2f& Position, const Color& Col = Color(255, 255, 255), const Color& OutlineCol = Color(0, 0, 0));
+    void setTexture(const Texture* texture, bool resetRect = false);
 
     ////////////////////////////////////////////////////////////
-    /// Get the number of points composing the shape
+    /// \brief Set the sub-rectangle of the texture that the shape will display
     ///
-    /// \param Total number of points
+    /// The texture rect is useful when you don't want to display
+    /// the whole texture, but rather a part of it.
+    /// By default, the texture rect covers the entire texture.
     ///
-    ////////////////////////////////////////////////////////////
-    unsigned int GetNbPoints() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Enable or disable filling the shape.
-    /// Fill is enabled by default
+    /// \param rect Rectangle defining the region of the texture to display
     ///
-    /// \param Enable : True to enable, false to disable
+    /// \see getTextureRect, setTexture
     ///
     ////////////////////////////////////////////////////////////
-    void EnableFill(bool Enable);
+    void setTextureRect(const IntRect& rect);
 
     ////////////////////////////////////////////////////////////
-    /// Enable or disable drawing the shape outline.
-    /// Outline is enabled by default
+    /// \brief Set the fill color of the shape
     ///
-    /// \param Enable : True to enable, false to disable
+    /// This color is modulated (multiplied) with the shape's
+    /// texture if any. It can be used to colorize the shape,
+    /// or change its global opacity.
+    /// You can use sf::Color::Transparent to make the inside of
+    /// the shape transparent, and have the outline alone.
+    /// By default, the shape's fill color is opaque white.
     ///
-    ////////////////////////////////////////////////////////////
-    void EnableOutline(bool Enable);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the position of a point
+    /// \param color New color of the shape
     ///
-    /// \param Index :    Index of the point, in range [0, GetNbPoints() - 1]
-    /// \param Position : New position of the Index-th point
+    /// \see getFillColor, setOutlineColor
     ///
     ////////////////////////////////////////////////////////////
-    void SetPointPosition(unsigned int Index, const Vector2f& Position);
+    void setFillColor(const Color& color);
 
     ////////////////////////////////////////////////////////////
-    /// Set the position of a point
+    /// \brief Set the outline color of the shape
+    ///
+    /// By default, the shape's outline color is opaque white.
+    ///
+    /// \param color New outline color of the shape
     ///
-    /// \param Index : Index of the point, in range [0, GetNbPoints() - 1]
-    /// \param X :     New X coordinate of the Index-th point
-    /// \param Y :     New Y coordinate of the Index-th point
+    /// \see getOutlineColor, setFillColor
     ///
     ////////////////////////////////////////////////////////////
-    void SetPointPosition(unsigned int Index, float X, float Y);
+    void setOutlineColor(const Color& color);
 
     ////////////////////////////////////////////////////////////
-    /// Set the color of a point
+    /// \brief Set the thickness of the shape's outline
+    ///
+    /// Note that negative values are allowed (so that the outline
+    /// expands towards the center of the shape), and using zero
+    /// disables the outline.
+    /// By default, the outline thickness is 0.
+    ///
+    /// \param thickness New outline thickness
     ///
-    /// \param Index : Index of the point, in range [0, GetNbPoints() - 1]
-    /// \param Col :   New color of the Index-th point
+    /// \see getOutlineThickness
     ///
     ////////////////////////////////////////////////////////////
-    void SetPointColor(unsigned int Index, const Color& Col);
+    void setOutlineThickness(float thickness);
 
     ////////////////////////////////////////////////////////////
-    /// Set the outline color of a point
+    /// \brief Get the source texture of the shape
     ///
-    /// \param Index :      Index of the point, in range [0, GetNbPoints() - 1]
-    /// \param OutlineCol : New outline color of the Index-th point
+    /// If the shape has no source texture, a NULL pointer is returned.
+    /// The returned pointer is const, which means that you can't
+    /// modify the texture when you retrieve it with this function.
+    ///
+    /// \return Pointer to the shape's texture
+    ///
+    /// \see setTexture
     ///
     ////////////////////////////////////////////////////////////
-    void SetPointOutlineColor(unsigned int Index, const Color& OutlineCol);
+    const Texture* getTexture() const;
 
     ////////////////////////////////////////////////////////////
-    /// Change the width of the shape outline
+    /// \brief Get the sub-rectangle of the texture displayed by the shape
     ///
-    /// \param Width : New width
+    /// \return Texture rectangle of the shape
+    ///
+    /// \see setTextureRect
     ///
     ////////////////////////////////////////////////////////////
-    void SetOutlineWidth(float Width);
+    const IntRect& getTextureRect() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the position of a point
+    /// \brief Get the fill color of the shape
     ///
-    /// \param Index : Index of the point, in range [0, GetNbPoints() - 1]
+    /// \return Fill color of the shape
     ///
-    /// \return Position of the Index-th point
+    /// \see setFillColor
     ///
     ////////////////////////////////////////////////////////////
-    const Vector2f& GetPointPosition(unsigned int Index) const;
+    const Color& getFillColor() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the color of a point
+    /// \brief Get the outline color of the shape
     ///
-    /// \param Index : Index of the point, in range [0, GetNbPoints() - 1]
+    /// \return Outline color of the shape
     ///
-    /// \return Color of the Index-th point
+    /// \see setOutlineColor
     ///
     ////////////////////////////////////////////////////////////
-    const Color& GetPointColor(unsigned int Index) const;
+    const Color& getOutlineColor() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the outline color of a point
+    /// \brief Get the outline thickness of the shape
     ///
-    /// \param Index : Index of the point, in range [0, GetNbPoints() - 1]
+    /// \return Outline thickness of the shape
     ///
-    /// \return Outline color of the Index-th point
+    /// \see setOutlineThickness
     ///
     ////////////////////////////////////////////////////////////
-    const Color& GetPointOutlineColor(unsigned int Index) const;
+    float getOutlineThickness() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the width of the shape outline
+    /// \brief Get the total number of points of the shape
+    ///
+    /// \return Number of points of the shape
     ///
-    /// \return Current outline width
+    /// \see getPoint
     ///
     ////////////////////////////////////////////////////////////
-    float GetOutlineWidth() const;
+    virtual unsigned int getPointCount() const = 0;
 
     ////////////////////////////////////////////////////////////
-    /// Create a shape made of a single line (use floats)
+    /// \brief Get a point of the shape
     ///
-    /// \param P1X, P1Y :   Position of the first point
-    /// \param P2X, P2Y :   Position second point
-    /// \param Thickness :  Line thickness
-    /// \param Col :        Color used to draw the line
-    /// \param Outline :    Outline width (0 by default)
-    /// \param OutlineCol : Color used to draw the outline (black by default)
+    /// The returned point is in local coordinates, that is,
+    /// the shape's transforms (position, rotation, scale) are
+    /// not taken into account.
+    /// The result is undefined if \a index is out of the valid range.
+    ///
+    /// \param index Index of the point to get, in range [0 .. getPointCount() - 1]
+    ///
+    /// \return index-th point of the shape
+    ///
+    /// \see getPointCount
     ///
     ////////////////////////////////////////////////////////////
-    static Shape Line(float P1X, float P1Y, float P2X, float P2Y, float Thickness, const Color& Col, float Outline = 0.f, const Color& OutlineCol = sf::Color(0, 0, 0));
+    virtual Vector2f getPoint(unsigned int index) const = 0;
 
     ////////////////////////////////////////////////////////////
-    /// Create a shape made of a single line (use vectors)
+    /// \brief Get the local bounding rectangle of the entity
     ///
-    /// \param P1X, P1Y :   Position of the first point
-    /// \param P2X, P2Y :   Position second point
-    /// \param Thickness :  Line thickness
-    /// \param Col :        Color used to draw the line
-    /// \param Outline :    Outline width (0 by default)
-    /// \param OutlineCol : Color used to draw the outline (black by default)
+    /// The returned rectangle is in local coordinates, which means
+    /// that it ignores the transformations (translation, rotation,
+    /// scale, ...) that are applied to the entity.
+    /// In other words, this function returns the bounds of the
+    /// entity in the entity's coordinate system.
+    ///
+    /// \return Local bounding rectangle of the entity
     ///
     ////////////////////////////////////////////////////////////
-    static Shape Line(const Vector2f& P1, const Vector2f& P2, float Thickness, const Color& Col, float Outline = 0.f, const Color& OutlineCol = sf::Color(0, 0, 0));
+    FloatRect getLocalBounds() const;
 
     ////////////////////////////////////////////////////////////
-    /// Create a shape made of a single rectangle (use floats)
+    /// \brief Get the global bounding rectangle of the entity
+    ///
+    /// The returned rectangle is in global coordinates, which means
+    /// that it takes in account the transformations (translation,
+    /// rotation, scale, ...) that are applied to the entity.
+    /// In other words, this function returns the bounds of the
+    /// sprite in the global 2D world's coordinate system.
     ///
-    /// \param P1X, P1Y :   Position of the first point
-    /// \param P2X, P2Y :   Position second point
-    /// \param Col :        Color used to fill the rectangle
-    /// \param Outline :    Outline width (0 by default)
-    /// \param OutlineCol : Color used to draw the outline (black by default)
+    /// \return Global bounding rectangle of the entity
     ///
     ////////////////////////////////////////////////////////////
-    static Shape Rectangle(float P1X, float P1Y, float P2X, float P2Y, const Color& Col, float Outline = 0.f, const Color& OutlineCol = sf::Color(0, 0, 0));
+    FloatRect getGlobalBounds() const;
+
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// Create a shape made of a single rectangle (use vectors)
-    ///
-    /// \param P1 :         Position of the first point
-    /// \param P2 :         Position second point
-    /// \param Col :        Color used to fill the rectangle
-    /// \param Outline :    Outline width (0 by default)
-    /// \param OutlineCol : Color used to draw the outline (black by default)
+    /// \brief Default constructor
     ///
     ////////////////////////////////////////////////////////////
-    static Shape Rectangle(const Vector2f& P1, const Vector2f& P2, const Color& Col, float Outline = 0.f, const Color& OutlineCol = sf::Color(0, 0, 0));
+    Shape();
 
     ////////////////////////////////////////////////////////////
-    /// Create a shape made of a single circle (use floats)
+    /// \brief Recompute the internal geometry of the shape
     ///
-    /// \param X, Y :       Position of the center
-    /// \param Radius :     Radius
-    /// \param Col :        Color used to fill the circle
-    /// \param Outline :    Outline width (0 by default)
-    /// \param OutlineCol : Color used to draw the outline (black by default)
+    /// This function must be called by the derived class everytime
+    /// the shape's points change (i.e. the result of either
+    /// getPointCount or getPoint is different).
     ///
     ////////////////////////////////////////////////////////////
-    static Shape Circle(float X, float Y, float Radius, const Color& Col, float Outline = 0.f, const Color& OutlineCol = sf::Color(0, 0, 0));
+    void update();
+
+private:
 
     ////////////////////////////////////////////////////////////
-    /// Create a shape made of a single circle (use vectors)
+    /// \brief Draw the shape to a render target
     ///
-    /// \param Center :     Position of the center
-    /// \param Radius :     Radius
-    /// \param Col :        Color used to fill the circle
-    /// \param Outline :    Outline width (0 by default)
-    /// \param OutlineCol : Color used to draw the outline (black by default)
+    /// \param target Render target to draw to
+    /// \param states Current render states
     ///
     ////////////////////////////////////////////////////////////
-    static Shape Circle(const Vector2f& Center, float Radius, const Color& Col, float Outline = 0.f, const Color& OutlineCol = sf::Color(0, 0, 0));
-
-protected :
+    virtual void draw(RenderTarget& target, RenderStates states) const;
 
     ////////////////////////////////////////////////////////////
-    /// /see Drawable::Render
+    /// \brief Update the fill vertices' color
     ///
     ////////////////////////////////////////////////////////////
-    virtual void Render(RenderTarget& Target) const;
-
-private :
+    void updateFillColors();
 
     ////////////////////////////////////////////////////////////
-    /// Compile the shape : compute its center and its outline
+    /// \brief Update the fill vertices' texture coordinates
     ///
     ////////////////////////////////////////////////////////////
-    void Compile();
+    void updateTexCoords();
 
     ////////////////////////////////////////////////////////////
-    /// Compute the normal of a given 2D segment
-    ///
-    /// \param P1 :     First point of the segment
-    /// \param P2 :     Second point of the segment
-    /// \param Normal : Calculated normal
-    ///
-    /// \return False if the normal couldn't be calculated (segment is null)
+    /// \brief Update the outline vertices' position
     ///
     ////////////////////////////////////////////////////////////
-    static bool ComputeNormal(const Vector2f& P1, const Vector2f& P2, Vector2f& Normal);
+    void updateOutline();
 
     ////////////////////////////////////////////////////////////
-    /// Defines a simple 2D point
+    /// \brief Update the outline vertices' color
+    ///
     ////////////////////////////////////////////////////////////
-    struct Point
-    {
-        Point(const Vector2f& Pos = Vector2f(0, 0), const Color& C = Color(255, 255, 255), const Color& OutlineC = Color(255, 255, 255));
+    void updateOutlineColors();
 
-        Vector2f Position;   ///< Position
-        Vector2f Normal;     ///< Extruded normal
-        Color    Col;        ///< Color of the point
-        Color    OutlineCol; ///< Outline color of the point
-    };
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    std::vector<Point> myPoints;           ///< Points composing the shape
-    float              myOutline;          ///< Outline width
-    bool               myIsFillEnabled;    ///< Should we draw the inside if the shape ?
-    bool               myIsOutlineEnabled; ///< Should we draw the outline if the shape ?
-    bool               myIsCompiled;       ///< Compiled state of the shape
+    const Texture* m_texture;          ///< Texture of the shape
+    IntRect        m_textureRect;      ///< Rectangle defining the area of the source texture to display
+    Color          m_fillColor;        ///< Fill color
+    Color          m_outlineColor;     ///< Outline color
+    float          m_outlineThickness; ///< Thickness of the shape's outline
+    VertexArray    m_vertices;         ///< Vertex array containing the fill geometry
+    VertexArray    m_outlineVertices;  ///< Vertex array containing the outline geometry
+    FloatRect      m_insideBounds;     ///< Bounding rectangle of the inside (fill)
+    FloatRect      m_bounds;           ///< Bounding rectangle of the whole shape (outline + fill)
 };
 
 } // namespace sf
 
 
 #endif // SFML_SHAPE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Shape
+/// \ingroup graphics
+///
+/// sf::Shape is a drawable class that allows to define and
+/// display a custom convex shape on a render target.
+/// It's only an abstract base, it needs to be specialized for
+/// concrete types of shapes (circle, rectangle, convex polygon,
+/// star, ...).
+///
+/// In addition to the attributes provided by the specialized
+/// shape classes, a shape always has the following attributes:
+/// \li a texture
+/// \li a texture rectangle
+/// \li a fill color
+/// \li an outline color
+/// \li an outline thickness
+///
+/// Each feature is optional, and can be disabled easily:
+/// \li the texture can be null
+/// \li the fill/outline colors can be sf::Color::Transparent
+/// \li the outline thickness can be zero
+///
+/// You can write your own derived shape class, there are only
+/// two virtual functions to override:
+/// \li getPointCount must return the number of points of the shape
+/// \li getPoint must return the points of the shape
+///
+/// \see sf::RectangleShape, sf::CircleShape, sf::ConvexShape, sf::Transformable
+///
+////////////////////////////////////////////////////////////
index f805b865bde04eeb6b23061252c544732c04d01a..2b4838424478b64ee241e801161db60ab6d477cd 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/System/Resource.hpp>
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Drawable.hpp>
+#include <SFML/Graphics/Transformable.hpp>
+#include <SFML/Graphics/Vertex.hpp>
 #include <SFML/Graphics/Rect.hpp>
 
 
 namespace sf
 {
-class Image;
+class Texture;
 
 ////////////////////////////////////////////////////////////
-/// Sprite defines a sprite : texture, transformations,
-/// color, and draw on screen
+/// \brief Drawable representation of a texture, with its
+///        own transformations, color, etc.
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Sprite : public Drawable
+class SFML_GRAPHICS_API Sprite : public Drawable, public Transformable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// Creates an empty sprite with no source texture.
     ///
     ////////////////////////////////////////////////////////////
     Sprite();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the sprite from a source image
+    /// \brief Construct the sprite from a source texture
+    ///
+    /// \param texture Source texture
     ///
-    /// \param Img :      Image of the sprite
-    /// \param Position : Position of the sprite (0, 0 by default)
-    /// \param Scale :    Scale factor (1, 1 by default)
-    /// \param Rotation : Orientation, in degrees (0 by default)
-    /// \param Col :      Color of the sprite (white by default)
+    /// \see setTexture
     ///
     ////////////////////////////////////////////////////////////
-    explicit Sprite(const Image& Img, const Vector2f& Position = Vector2f(0, 0), const Vector2f& Scale = Vector2f(1, 1), float Rotation = 0.f, const Color& Col = Color(255, 255, 255, 255));
+    explicit Sprite(const Texture& texture);
 
     ////////////////////////////////////////////////////////////
-    /// Change the image of the sprite
+    /// \brief Construct the sprite from a sub-rectangle of a source texture
     ///
-    /// \param Img : New image
+    /// \param texture   Source texture
+    /// \param rectangle Sub-rectangle of the texture to assign to the sprite
+    ///
+    /// \see setTexture, setTextureRect
     ///
     ////////////////////////////////////////////////////////////
-    void SetImage(const Image& Img);
+    Sprite(const Texture& texture, const IntRect& rectangle);
 
     ////////////////////////////////////////////////////////////
-    /// Set the sub-rectangle of the sprite inside the source image.
-    /// By default, the subrect covers the entire source image
+    /// \brief Change the source texture of the sprite
+    ///
+    /// The \a texture argument refers to a texture that must
+    /// exist as long as the sprite uses it. Indeed, the sprite
+    /// doesn't store its own copy of the texture, but rather keeps
+    /// a pointer to the one that you passed to this function.
+    /// If the source texture is destroyed and the sprite tries to
+    /// use it, the behavior is undefined.
+    /// If \a resetRect is true, the TextureRect property of
+    /// the sprite is automatically adjusted to the size of the new
+    /// texture. If it is false, the texture rect is left unchanged.
     ///
-    /// \param SubRect : New sub-rectangle
+    /// \param texture   New texture
+    /// \param resetRect Should the texture rect be reset to the size of the new texture?
+    ///
+    /// \see getTexture, setTextureRect
     ///
     ////////////////////////////////////////////////////////////
-    void SetSubRect(const IntRect& SubRect);
+    void setTexture(const Texture& texture, bool resetRect = false);
 
     ////////////////////////////////////////////////////////////
-    /// Resize the sprite (by changing its scale factors) (take 2 values).
-    /// The default size is defined by the subrect
+    /// \brief Set the sub-rectangle of the texture that the sprite will display
+    ///
+    /// The texture rect is useful when you don't want to display
+    /// the whole texture, but rather a part of it.
+    /// By default, the texture rect covers the entire texture.
+    ///
+    /// \param rectangle Rectangle defining the region of the texture to display
     ///
-    /// \param Width :  New width (must be strictly positive)
-    /// \param Height : New height (must be strictly positive)
+    /// \see getTextureRect, setTexture
     ///
     ////////////////////////////////////////////////////////////
-    void Resize(float Width, float Height);
+    void setTextureRect(const IntRect& rectangle);
 
     ////////////////////////////////////////////////////////////
-    /// Resize the sprite (by changing its scale factors) (take a 2D vector).
-    /// The default size is defined by the subrect
+    /// \brief Set the global color of the sprite
     ///
-    /// \param Size : New size (both coordinates must be strictly positive)
+    /// This color is modulated (multiplied) with the sprite's
+    /// texture. It can be used to colorize the sprite, or change
+    /// its global opacity.
+    /// By default, the sprite's color is opaque white.
+    ///
+    /// \param color New color of the sprite
+    ///
+    /// \see getColor
     ///
     ////////////////////////////////////////////////////////////
-    void Resize(const Vector2f& Size);
+    void setColor(const Color& color);
 
     ////////////////////////////////////////////////////////////
-    /// Flip the sprite horizontally
+    /// \brief Get the source texture of the sprite
+    ///
+    /// If the sprite has no source texture, a NULL pointer is returned.
+    /// The returned pointer is const, which means that you can't
+    /// modify the texture when you retrieve it with this function.
     ///
-    /// \param Flipped : True to flip the sprite
+    /// \return Pointer to the sprite's texture
+    ///
+    /// \see setTexture
     ///
     ////////////////////////////////////////////////////////////
-    void FlipX(bool Flipped);
+    const Texture* getTexture() const;
 
     ////////////////////////////////////////////////////////////
-    /// Flip the sprite vertically
+    /// \brief Get the sub-rectangle of the texture displayed by the sprite
+    ///
+    /// \return Texture rectangle of the sprite
     ///
-    /// \param Flipped : True to flip the sprite
+    /// \see setTextureRect
     ///
     ////////////////////////////////////////////////////////////
-    void FlipY(bool Flipped);
+    const IntRect& getTextureRect() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the source image of the sprite
+    /// \brief Get the global color of the sprite
+    ///
+    /// \return Global color of the sprite
     ///
-    /// \return Pointer to the image (can be NULL)
+    /// \see setColor
     ///
     ////////////////////////////////////////////////////////////
-    const Image* GetImage() const;
+    const Color& getColor() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the sub-rectangle of the sprite inside the source image
+    /// \brief Get the local bounding rectangle of the entity
     ///
-    /// \return Sub-rectangle
+    /// The returned rectangle is in local coordinates, which means
+    /// that it ignores the transformations (translation, rotation,
+    /// scale, ...) that are applied to the entity.
+    /// In other words, this function returns the bounds of the
+    /// entity in the entity's coordinate system.
+    ///
+    /// \return Local bounding rectangle of the entity
     ///
     ////////////////////////////////////////////////////////////
-    const IntRect& GetSubRect() const;
+    FloatRect getLocalBounds() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the sprite size
+    /// \brief Get the global bounding rectangle of the entity
+    ///
+    /// The returned rectangle is in global coordinates, which means
+    /// that it takes in account the transformations (translation,
+    /// rotation, scale, ...) that are applied to the entity.
+    /// In other words, this function returns the bounds of the
+    /// sprite in the global 2D world's coordinate system.
     ///
-    /// \return Size of the sprite
+    /// \return Global bounding rectangle of the entity
     ///
     ////////////////////////////////////////////////////////////
-    Vector2f GetSize() const;
+    FloatRect getGlobalBounds() const;
+
+private:
 
     ////////////////////////////////////////////////////////////
-    /// Get the color of a given pixel in the sprite
-    /// (point is in local coordinates)
+    /// \brief Draw the sprite to a render target
     ///
-    /// \param X : X coordinate of the pixel to get
-    /// \param Y : Y coordinate of the pixel to get
-    ///
-    /// \return Color of pixel (X, Y)
+    /// \param target Render target to draw to
+    /// \param states Current render states
     ///
     ////////////////////////////////////////////////////////////
-    Color GetPixel(unsigned int X, unsigned int Y) const;
-
-protected :
+    virtual void draw(RenderTarget& target, RenderStates states) const;
 
     ////////////////////////////////////////////////////////////
-    /// /see Drawable::Render
+    /// \brief Update the vertices' positions
     ///
     ////////////////////////////////////////////////////////////
-    virtual void Render(RenderTarget& Target) const;
+    void updatePositions();
 
-private :
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the vertices' texture coordinates
+    ///
+    ////////////////////////////////////////////////////////////
+    void updateTexCoords();
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    ResourcePtr<Image> myImage;      ///< Image used to draw the sprite
-    IntRect            mySubRect;    ///< Sub-rectangle of source image to assign to the sprite
-    bool               myIsFlippedX; ///< Is the sprite flipped on the X axis ?
-    bool               myIsFlippedY; ///< Is the sprite flipped on the Y axis ?
+    Vertex         m_vertices[4]; ///< Vertices defining the sprite's geometry
+    const Texture* m_texture;     ///< Texture of the sprite
+    IntRect        m_textureRect; ///< Rectangle defining the area of the source texture to display
 };
 
 } // namespace sf
 
 
 #endif // SFML_SPRITE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Sprite
+/// \ingroup graphics
+///
+/// sf::Sprite is a drawable class that allows to easily display
+/// a texture (or a part of it) on a render target.
+///
+/// It inherits all the functions from sf::Transformable:
+/// position, rotation, scale, origin. It also adds sprite-specific
+/// properties such as the texture to use, the part of it to display,
+/// and some convenience functions to change the overall color of the
+/// sprite, or to get its bounding rectangle.
+///
+/// sf::Sprite works in combination with the sf::Texture class, which
+/// loads and provides the pixel data of a given texture.
+///
+/// The separation of sf::Sprite and sf::Texture allows more flexibility
+/// and better performances: indeed a sf::Texture is a heavy resource,
+/// and any operation on it is slow (often too slow for real-time
+/// applications). On the other side, a sf::Sprite is a lightweight
+/// object which can use the pixel data of a sf::Texture and draw
+/// it with its own transformation/color/blending attributes.
+///
+/// It is important to note that the sf::Sprite instance doesn't
+/// copy the texture that it uses, it only keeps a reference to it.
+/// Thus, a sf::Texture must not be destroyed while it is
+/// used by a sf::Sprite (i.e. never write a function that
+/// uses a local sf::Texture instance for creating a sprite).
+///
+/// See also the note on coordinates and undistorted rendering in sf::Transformable.
+///
+/// Usage example:
+/// \code
+/// // Declare and load a texture
+/// sf::Texture texture;
+/// texture.loadFromFile("texture.png");
+/// 
+/// // Create a sprite
+/// sf::Sprite sprite;
+/// sprite.setTexture(texture);
+/// sprite.setTextureRect(sf::IntRect(10, 10, 50, 30));
+/// sprite.setColor(sf::Color(255, 255, 255, 200));
+/// sprite.setPosition(100, 25);
+///
+/// // Draw it
+/// window.draw(sprite);
+/// \endcode
+///
+/// \see sf::Texture, sf::Transformable
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/String.hpp b/dependencies64/sfml/include/SFML/Graphics/String.hpp
deleted file mode 100644 (file)
index fb92bde..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_STRING_HPP
-#define SFML_STRING_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/System/Resource.hpp>
-#include <SFML/System/Unicode.hpp>
-#include <SFML/Graphics/Drawable.hpp>
-#include <SFML/Graphics/Font.hpp>
-#include <SFML/Graphics/Rect.hpp>
-#include <string>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// String defines a graphical 2D text, that can be drawn on screen
-////////////////////////////////////////////////////////////
-class SFML_API String : public Drawable
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Enumerate the string drawing styles
-    ////////////////////////////////////////////////////////////
-    enum Style
-    {
-        Regular    = 0,      ///< Regular characters, no style
-        Bold       = 1 << 0, ///< Characters are bold
-        Italic     = 1 << 1, ///< Characters are in italic
-        Underlined = 1 << 2  ///< Characters are underlined
-    };
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    String();
-
-    ////////////////////////////////////////////////////////////
-    /// Construct the string from any kind of text
-    ///
-    /// \param Text : Text assigned to the string
-    /// \param Font : Font used to draw the string (SFML built-in font by default)
-    /// \param Size : Characters size (30 by default)
-    ///
-    ////////////////////////////////////////////////////////////
-    explicit String(const Unicode::Text& Text, const Font& CharFont = Font::GetDefaultFont(), float Size = 30.f);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the text (from any kind of string)
-    ///
-    /// \param Text : New text
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetText(const Unicode::Text& Text);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the font of the string
-    ///
-    /// \param Font : Font to use
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetFont(const Font& CharFont);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the size of the string
-    /// The default size is 30
-    ///
-    /// \param Size : New size, in pixels
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetSize(float Size);
-
-    ////////////////////////////////////////////////////////////
-    /// Set the style of the text
-    /// The default style is Regular
-    ///
-    /// \param TextStyle : New text style, (combination of Style enum values)
-    ///
-    ////////////////////////////////////////////////////////////
-    void SetStyle(unsigned long TextStyle);
-
-    ////////////////////////////////////////////////////////////
-    /// Get the text (the returned text can be converted implicitely to any kind of string)
-    ///
-    /// \return String's text
-    ///
-    ////////////////////////////////////////////////////////////
-    const Unicode::Text& GetText() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the font used by the string
-    ///
-    /// \return Font used
-    ///
-    ////////////////////////////////////////////////////////////
-    const Font& GetFont() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the size of the characters
-    ///
-    /// \return Size of the characters
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetSize() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the style of the text
-    ///
-    /// \return Current string style (combination of Style enum values)
-    ///
-    ////////////////////////////////////////////////////////////
-    unsigned long GetStyle() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Return the visual position of the Index-th character of the string,
-    /// in coordinates relative to the string
-    /// (note : translation, center, rotation and scale are not applied)
-    ///
-    /// \param Index : Index of the character
-    ///
-    /// \return Position of the Index-th character (end of string if Index is out of range)
-    ///
-    ////////////////////////////////////////////////////////////
-    sf::Vector2f GetCharacterPos(std::size_t Index) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the string rectangle on screen
-    ///
-    /// \return Rectangle contaning the string in screen coordinates
-    ///
-    ////////////////////////////////////////////////////////////
-    FloatRect GetRect() const;
-
-protected :
-
-    ////////////////////////////////////////////////////////////
-    /// /see Drawable::Render
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual void Render(RenderTarget& Target) const;
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    /// Recompute the bounding rectangle of the text
-    ///
-    ////////////////////////////////////////////////////////////
-    void RecomputeRect();
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    Unicode::Text     myText;           ///< Text to display
-    ResourcePtr<Font> myFont;           ///< Font used to display the string
-    float             mySize;           ///< Size of the characters
-    unsigned long     myStyle;          ///< Text style (see Style enum)
-    FloatRect         myBaseRect;       ///< Bounding rectangle of the text in object coordinates
-    bool              myNeedRectUpdate; ///< Does the bounding rect need an update ?
-};
-
-} // namespace sf
-
-
-#endif // SFML_STRING_HPP
diff --git a/dependencies64/sfml/include/SFML/Graphics/Text.hpp b/dependencies64/sfml/include/SFML/Graphics/Text.hpp
new file mode 100644 (file)
index 0000000..919a2f7
--- /dev/null
@@ -0,0 +1,372 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TEXT_HPP
+#define SFML_TEXT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Drawable.hpp>
+#include <SFML/Graphics/Transformable.hpp>
+#include <SFML/Graphics/Font.hpp>
+#include <SFML/Graphics/Rect.hpp>
+#include <SFML/Graphics/VertexArray.hpp>
+#include <SFML/System/String.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Graphical text that can be drawn to a render target
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API Text : public Drawable, public Transformable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enumeration of the string drawing styles
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Style
+    {
+        Regular       = 0,      ///< Regular characters, no style
+        Bold          = 1 << 0, ///< Bold characters
+        Italic        = 1 << 1, ///< Italic characters
+        Underlined    = 1 << 2, ///< Underlined characters
+        StrikeThrough = 1 << 3  ///< Strike through characters
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Creates an empty text.
+    ///
+    ////////////////////////////////////////////////////////////
+    Text();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the text from a string, font and size
+    ///
+    /// Note that if the used font is a bitmap font, it is not
+    /// scalable, thus not all requested sizes will be available
+    /// to use. This needs to be taken into consideration when
+    /// setting the character size. If you need to display text
+    /// of a certain size, make sure the corresponding bitmap
+    /// font that supports that size is used.
+    ///
+    /// \param string         Text assigned to the string
+    /// \param font           Font used to draw the string
+    /// \param characterSize  Base size of characters, in pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    Text(const String& string, const Font& font, unsigned int characterSize = 30);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the text's string
+    ///
+    /// The \a string argument is a sf::String, which can
+    /// automatically be constructed from standard string types.
+    /// So, the following calls are all valid:
+    /// \code
+    /// text.setString("hello");
+    /// text.setString(L"hello");
+    /// text.setString(std::string("hello"));
+    /// text.setString(std::wstring(L"hello"));
+    /// \endcode
+    /// A text's string is empty by default.
+    ///
+    /// \param string New string
+    ///
+    /// \see getString
+    ///
+    ////////////////////////////////////////////////////////////
+    void setString(const String& string);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the text's font
+    ///
+    /// The \a font argument refers to a font that must
+    /// exist as long as the text uses it. Indeed, the text
+    /// doesn't store its own copy of the font, but rather keeps
+    /// a pointer to the one that you passed to this function.
+    /// If the font is destroyed and the text tries to
+    /// use it, the behavior is undefined.
+    ///
+    /// \param font New font
+    ///
+    /// \see getFont
+    ///
+    ////////////////////////////////////////////////////////////
+    void setFont(const Font& font);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the character size
+    ///
+    /// The default size is 30.
+    ///
+    /// Note that if the used font is a bitmap font, it is not
+    /// scalable, thus not all requested sizes will be available
+    /// to use. This needs to be taken into consideration when
+    /// setting the character size. If you need to display text
+    /// of a certain size, make sure the corresponding bitmap
+    /// font that supports that size is used.
+    ///
+    /// \param size New character size, in pixels
+    ///
+    /// \see getCharacterSize
+    ///
+    ////////////////////////////////////////////////////////////
+    void setCharacterSize(unsigned int size);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the text's style
+    ///
+    /// You can pass a combination of one or more styles, for
+    /// example sf::Text::Bold | sf::Text::Italic.
+    /// The default style is sf::Text::Regular.
+    ///
+    /// \param style New style
+    ///
+    /// \see getStyle
+    ///
+    ////////////////////////////////////////////////////////////
+    void setStyle(Uint32 style);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the global color of the text
+    ///
+    /// By default, the text's color is opaque white.
+    ///
+    /// \param color New color of the text
+    ///
+    /// \see getColor
+    ///
+    ////////////////////////////////////////////////////////////
+    void setColor(const Color& color);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the text's string
+    ///
+    /// The returned string is a sf::String, which can automatically
+    /// be converted to standard string types. So, the following
+    /// lines of code are all valid:
+    /// \code
+    /// sf::String   s1 = text.getString();
+    /// std::string  s2 = text.getString();
+    /// std::wstring s3 = text.getString();
+    /// \endcode
+    ///
+    /// \return Text's string
+    ///
+    /// \see setString
+    ///
+    ////////////////////////////////////////////////////////////
+    const String& getString() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the text's font
+    ///
+    /// If the text has no font attached, a NULL pointer is returned.
+    /// The returned pointer is const, which means that you
+    /// cannot modify the font when you get it from this function.
+    ///
+    /// \return Pointer to the text's font
+    ///
+    /// \see setFont
+    ///
+    ////////////////////////////////////////////////////////////
+    const Font* getFont() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the character size
+    ///
+    /// \return Size of the characters, in pixels
+    ///
+    /// \see setCharacterSize
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned int getCharacterSize() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the text's style
+    ///
+    /// \return Text's style
+    ///
+    /// \see setStyle
+    ///
+    ////////////////////////////////////////////////////////////
+    Uint32 getStyle() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the global color of the text
+    ///
+    /// \return Global color of the text
+    ///
+    /// \see setColor
+    ///
+    ////////////////////////////////////////////////////////////
+    const Color& getColor() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the position of the \a index-th character
+    ///
+    /// This function computes the visual position of a character
+    /// from its index in the string. The returned position is
+    /// in global coordinates (translation, rotation, scale and
+    /// origin are applied).
+    /// If \a index is out of range, the position of the end of
+    /// the string is returned.
+    ///
+    /// \param index Index of the character
+    ///
+    /// \return Position of the character
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2f findCharacterPos(std::size_t index) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the local bounding rectangle of the entity
+    ///
+    /// The returned rectangle is in local coordinates, which means
+    /// that it ignores the transformations (translation, rotation,
+    /// scale, ...) that are applied to the entity.
+    /// In other words, this function returns the bounds of the
+    /// entity in the entity's coordinate system.
+    ///
+    /// \return Local bounding rectangle of the entity
+    ///
+    ////////////////////////////////////////////////////////////
+    FloatRect getLocalBounds() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the global bounding rectangle of the entity
+    ///
+    /// The returned rectangle is in global coordinates, which means
+    /// that it takes in account the transformations (translation,
+    /// rotation, scale, ...) that are applied to the entity.
+    /// In other words, this function returns the bounds of the
+    /// sprite in the global 2D world's coordinate system.
+    ///
+    /// \return Global bounding rectangle of the entity
+    ///
+    ////////////////////////////////////////////////////////////
+    FloatRect getGlobalBounds() const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Draw the text to a render target
+    ///
+    /// \param target Render target to draw to
+    /// \param states Current render states
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual void draw(RenderTarget& target, RenderStates states) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Make sure the text's geometry is updated
+    /// 
+    /// All the attributes related to rendering are cached, such
+    /// that the geometry is only updated when necessary.
+    ///
+    ////////////////////////////////////////////////////////////
+    void ensureGeometryUpdate() const;
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    String              m_string;             ///< String to display
+    const Font*         m_font;               ///< Font used to display the string
+    unsigned int        m_characterSize;      ///< Base size of characters, in pixels
+    Uint32              m_style;              ///< Text style (see Style enum)
+    Color               m_color;              ///< Text color
+    mutable VertexArray m_vertices;           ///< Vertex array containing the text's geometry
+    mutable FloatRect   m_bounds;             ///< Bounding rectangle of the text (in local coordinates)
+    mutable bool        m_geometryNeedUpdate; ///< Does the geometry need to be recomputed?
+};
+
+} // namespace sf
+
+
+#endif // SFML_TEXT_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Text
+/// \ingroup graphics
+///
+/// sf::Text is a drawable class that allows to easily display
+/// some text with custom style and color on a render target.
+///
+/// It inherits all the functions from sf::Transformable:
+/// position, rotation, scale, origin. It also adds text-specific
+/// properties such as the font to use, the character size,
+/// the font style (bold, italic, underlined, strike through), the
+/// global color and the text to display of course.
+/// It also provides convenience functions to calculate the
+/// graphical size of the text, or to get the global position
+/// of a given character.
+///
+/// sf::Text works in combination with the sf::Font class, which
+/// loads and provides the glyphs (visual characters) of a given font.
+///
+/// The separation of sf::Font and sf::Text allows more flexibility
+/// and better performances: indeed a sf::Font is a heavy resource,
+/// and any operation on it is slow (often too slow for real-time
+/// applications). On the other side, a sf::Text is a lightweight
+/// object which can combine the glyphs data and metrics of a sf::Font
+/// to display any text on a render target.
+///
+/// It is important to note that the sf::Text instance doesn't
+/// copy the font that it uses, it only keeps a reference to it.
+/// Thus, a sf::Font must not be destructed while it is
+/// used by a sf::Text (i.e. never write a function that
+/// uses a local sf::Font instance for creating a text).
+///
+/// See also the note on coordinates and undistorted rendering in sf::Transformable.
+///
+/// Usage example:
+/// \code
+/// // Declare and load a font
+/// sf::Font font;
+/// font.loadFromFile("arial.ttf");
+/// 
+/// // Create a text
+/// sf::Text text("hello", font);
+/// text.setCharacterSize(30);
+/// text.setStyle(sf::Text::Bold);
+/// text.setColor(sf::Color::Red);
+///
+/// // Draw it
+/// window.draw(text);
+/// \endcode
+///
+/// \see sf::Font, sf::Transformable
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Texture.hpp b/dependencies64/sfml/include/SFML/Graphics/Texture.hpp
new file mode 100644 (file)
index 0000000..a68b076
--- /dev/null
@@ -0,0 +1,605 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TEXTURE_HPP
+#define SFML_TEXTURE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Image.hpp>
+#include <SFML/Window/GlResource.hpp>
+
+
+namespace sf
+{
+class Window;
+class RenderTarget;
+class RenderTexture;
+class InputStream;
+
+////////////////////////////////////////////////////////////
+/// \brief Image living on the graphics card that can be used for drawing
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API Texture : GlResource
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Types of texture coordinates that can be used for rendering
+    ///
+    ////////////////////////////////////////////////////////////
+    enum CoordinateType
+    {
+        Normalized, ///< Texture coordinates in range [0 .. 1]
+        Pixels      ///< Texture coordinates in range [0 .. size]
+    };
+
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Creates an empty texture.
+    ///
+    ////////////////////////////////////////////////////////////
+    Texture();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Copy constructor
+    ///
+    /// \param copy instance to copy
+    ///
+    ////////////////////////////////////////////////////////////
+    Texture(const Texture& copy);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    ~Texture();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create the texture
+    ///
+    /// If this function fails, the texture is left unchanged.
+    ///
+    /// \param width  Width of the texture
+    /// \param height Height of the texture
+    ///
+    /// \return True if creation was successful
+    ///
+    ////////////////////////////////////////////////////////////
+    bool create(unsigned int width, unsigned int height);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load the texture from a file on disk
+    ///
+    /// This function is a shortcut for the following code:
+    /// \code
+    /// sf::Image image;
+    /// image.loadFromFile(filename);
+    /// texture.loadFromImage(image, area);
+    /// \endcode
+    ///
+    /// The \a area argument can be used to load only a sub-rectangle
+    /// of the whole image. If you want the entire image then leave
+    /// the default value (which is an empty IntRect).
+    /// If the \a area rectangle crosses the bounds of the image, it
+    /// is adjusted to fit the image size.
+    ///
+    /// The maximum size for a texture depends on the graphics
+    /// driver and can be retrieved with the getMaximumSize function.
+    ///
+    /// If this function fails, the texture is left unchanged.
+    ///
+    /// \param filename Path of the image file to load
+    /// \param area     Area of the image to load
+    ///
+    /// \return True if loading was successful
+    ///
+    /// \see loadFromMemory, loadFromStream, loadFromImage
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromFile(const std::string& filename, const IntRect& area = IntRect());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load the texture from a file in memory
+    ///
+    /// This function is a shortcut for the following code:
+    /// \code
+    /// sf::Image image;
+    /// image.loadFromMemory(data, size);
+    /// texture.loadFromImage(image, area);
+    /// \endcode
+    ///
+    /// The \a area argument can be used to load only a sub-rectangle
+    /// of the whole image. If you want the entire image then leave
+    /// the default value (which is an empty IntRect).
+    /// If the \a area rectangle crosses the bounds of the image, it
+    /// is adjusted to fit the image size.
+    ///
+    /// The maximum size for a texture depends on the graphics
+    /// driver and can be retrieved with the getMaximumSize function.
+    ///
+    /// If this function fails, the texture is left unchanged.
+    ///
+    /// \param data Pointer to the file data in memory
+    /// \param size Size of the data to load, in bytes
+    /// \param area Area of the image to load
+    ///
+    /// \return True if loading was successful
+    ///
+    /// \see loadFromFile, loadFromStream, loadFromImage
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromMemory(const void* data, std::size_t size, const IntRect& area = IntRect());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load the texture from a custom stream
+    ///
+    /// This function is a shortcut for the following code:
+    /// \code
+    /// sf::Image image;
+    /// image.loadFromStream(stream);
+    /// texture.loadFromImage(image, area);
+    /// \endcode
+    ///
+    /// The \a area argument can be used to load only a sub-rectangle
+    /// of the whole image. If you want the entire image then leave
+    /// the default value (which is an empty IntRect).
+    /// If the \a area rectangle crosses the bounds of the image, it
+    /// is adjusted to fit the image size.
+    ///
+    /// The maximum size for a texture depends on the graphics
+    /// driver and can be retrieved with the getMaximumSize function.
+    ///
+    /// If this function fails, the texture is left unchanged.
+    ///
+    /// \param stream Source stream to read from
+    /// \param area   Area of the image to load
+    ///
+    /// \return True if loading was successful
+    ///
+    /// \see loadFromFile, loadFromMemory, loadFromImage
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromStream(sf::InputStream& stream, const IntRect& area = IntRect());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Load the texture from an image
+    ///
+    /// The \a area argument can be used to load only a sub-rectangle
+    /// of the whole image. If you want the entire image then leave
+    /// the default value (which is an empty IntRect).
+    /// If the \a area rectangle crosses the bounds of the image, it
+    /// is adjusted to fit the image size.
+    ///
+    /// The maximum size for a texture depends on the graphics
+    /// driver and can be retrieved with the getMaximumSize function.
+    ///
+    /// If this function fails, the texture is left unchanged.
+    ///
+    /// \param image Image to load into the texture
+    /// \param area  Area of the image to load
+    ///
+    /// \return True if loading was successful
+    ///
+    /// \see loadFromFile, loadFromMemory
+    ///
+    ////////////////////////////////////////////////////////////
+    bool loadFromImage(const Image& image, const IntRect& area = IntRect());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the size of the texture
+    ///
+    /// \return Size in pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2u getSize() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Copy the texture pixels to an image
+    ///
+    /// This function performs a slow operation that downloads
+    /// the texture's pixels from the graphics card and copies
+    /// them to a new image, potentially applying transformations
+    /// to pixels if necessary (texture may be padded or flipped).
+    ///
+    /// \return Image containing the texture's pixels
+    ///
+    /// \see loadFromImage
+    ///
+    ////////////////////////////////////////////////////////////
+    Image copyToImage() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the whole texture from an array of pixels
+    ///
+    /// The \a pixel array is assumed to have the same size as
+    /// the \a area rectangle, and to contain 32-bits RGBA pixels.
+    ///
+    /// No additional check is performed on the size of the pixel
+    /// array, passing invalid arguments will lead to an undefined
+    /// behavior.
+    ///
+    /// This function does nothing if \a pixels is null or if the
+    /// texture was not previously created.
+    ///
+    /// \param pixels Array of pixels to copy to the texture
+    ///
+    ////////////////////////////////////////////////////////////
+    void update(const Uint8* pixels);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update a part of the texture from an array of pixels
+    ///
+    /// The size of the \a pixel array must match the \a width and
+    /// \a height arguments, and it must contain 32-bits RGBA pixels.
+    ///
+    /// No additional check is performed on the size of the pixel
+    /// array or the bounds of the area to update, passing invalid
+    /// arguments will lead to an undefined behavior.
+    ///
+    /// This function does nothing if \a pixels is null or if the
+    /// texture was not previously created.
+    ///
+    /// \param pixels Array of pixels to copy to the texture
+    /// \param width  Width of the pixel region contained in \a pixels
+    /// \param height Height of the pixel region contained in \a pixels
+    /// \param x      X offset in the texture where to copy the source pixels
+    /// \param y      Y offset in the texture where to copy the source pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    void update(const Uint8* pixels, unsigned int width, unsigned int height, unsigned int x, unsigned int y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the texture from an image
+    ///
+    /// Although the source image can be smaller than the texture,
+    /// this function is usually used for updating the whole texture.
+    /// The other overload, which has (x, y) additional arguments,
+    /// is more convenient for updating a sub-area of the texture.
+    ///
+    /// No additional check is performed on the size of the image,
+    /// passing an image bigger than the texture will lead to an
+    /// undefined behavior.
+    ///
+    /// This function does nothing if the texture was not
+    /// previously created.
+    ///
+    /// \param image Image to copy to the texture
+    ///
+    ////////////////////////////////////////////////////////////
+    void update(const Image& image);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update a part of the texture from an image
+    ///
+    /// No additional check is performed on the size of the image,
+    /// passing an invalid combination of image size and offset
+    /// will lead to an undefined behavior.
+    ///
+    /// This function does nothing if the texture was not
+    /// previously created.
+    ///
+    /// \param image Image to copy to the texture
+    /// \param x     X offset in the texture where to copy the source image
+    /// \param y     Y offset in the texture where to copy the source image
+    ///
+    ////////////////////////////////////////////////////////////
+    void update(const Image& image, unsigned int x, unsigned int y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the texture from the contents of a window
+    ///
+    /// Although the source window can be smaller than the texture,
+    /// this function is usually used for updating the whole texture.
+    /// The other overload, which has (x, y) additional arguments,
+    /// is more convenient for updating a sub-area of the texture.
+    ///
+    /// No additional check is performed on the size of the window,
+    /// passing a window bigger than the texture will lead to an
+    /// undefined behavior.
+    ///
+    /// This function does nothing if either the texture or the window
+    /// was not previously created.
+    ///
+    /// \param window Window to copy to the texture
+    ///
+    ////////////////////////////////////////////////////////////
+    void update(const Window& window);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update a part of the texture from the contents of a window
+    ///
+    /// No additional check is performed on the size of the window,
+    /// passing an invalid combination of window size and offset
+    /// will lead to an undefined behavior.
+    ///
+    /// This function does nothing if either the texture or the window
+    /// was not previously created.
+    ///
+    /// \param window Window to copy to the texture
+    /// \param x      X offset in the texture where to copy the source window
+    /// \param y      Y offset in the texture where to copy the source window
+    ///
+    ////////////////////////////////////////////////////////////
+    void update(const Window& window, unsigned int x, unsigned int y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enable or disable the smooth filter
+    ///
+    /// When the filter is activated, the texture appears smoother
+    /// so that pixels are less noticeable. However if you want
+    /// the texture to look exactly the same as its source file,
+    /// you should leave it disabled.
+    /// The smooth filter is disabled by default.
+    ///
+    /// \param smooth True to enable smoothing, false to disable it
+    ///
+    /// \see isSmooth
+    ///
+    ////////////////////////////////////////////////////////////
+    void setSmooth(bool smooth);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether the smooth filter is enabled or not
+    ///
+    /// \return True if smoothing is enabled, false if it is disabled
+    ///
+    /// \see setSmooth
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isSmooth() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enable or disable repeating
+    ///
+    /// Repeating is involved when using texture coordinates
+    /// outside the texture rectangle [0, 0, width, height].
+    /// In this case, if repeat mode is enabled, the whole texture
+    /// will be repeated as many times as needed to reach the
+    /// coordinate (for example, if the X texture coordinate is
+    /// 3 * width, the texture will be repeated 3 times).
+    /// If repeat mode is disabled, the "extra space" will instead
+    /// be filled with border pixels.
+    /// Warning: on very old graphics cards, white pixels may appear
+    /// when the texture is repeated. With such cards, repeat mode
+    /// can be used reliably only if the texture has power-of-two
+    /// dimensions (such as 256x128).
+    /// Repeating is disabled by default.
+    ///
+    /// \param repeated True to repeat the texture, false to disable repeating
+    ///
+    /// \see isRepeated
+    ///
+    ////////////////////////////////////////////////////////////
+    void setRepeated(bool repeated);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether the texture is repeated or not
+    ///
+    /// \return True if repeat mode is enabled, false if it is disabled
+    ///
+    /// \see setRepeated
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isRepeated() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of assignment operator
+    ///
+    /// \param right Instance to assign
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    Texture& operator =(const Texture& right);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Bind a texture for rendering
+    ///
+    /// This function is not part of the graphics API, it mustn't be
+    /// used when drawing SFML entities. It must be used only if you
+    /// mix sf::Texture with OpenGL code.
+    ///
+    /// \code
+    /// sf::Texture t1, t2;
+    /// ...
+    /// sf::Texture::bind(&t1);
+    /// // draw OpenGL stuff that use t1...
+    /// sf::Texture::bind(&t2);
+    /// // draw OpenGL stuff that use t2...
+    /// sf::Texture::bind(NULL);
+    /// // draw OpenGL stuff that use no texture...
+    /// \endcode
+    ///
+    /// The \a coordinateType argument controls how texture
+    /// coordinates will be interpreted. If Normalized (the default), they
+    /// must be in range [0 .. 1], which is the default way of handling
+    /// texture coordinates with OpenGL. If Pixels, they must be given
+    /// in pixels (range [0 .. size]). This mode is used internally by
+    /// the graphics classes of SFML, it makes the definition of texture
+    /// coordinates more intuitive for the high-level API, users don't need
+    /// to compute normalized values.
+    ///
+    /// \param texture Pointer to the texture to bind, can be null to use no texture
+    /// \param coordinateType Type of texture coordinates to use
+    ///
+    ////////////////////////////////////////////////////////////
+    static void bind(const Texture* texture, CoordinateType coordinateType = Normalized);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the maximum texture size allowed
+    ///
+    /// This maximum size is defined by the graphics driver.
+    /// You can expect a value of 512 pixels for low-end graphics
+    /// card, and up to 8192 pixels or more for newer hardware.
+    ///
+    /// Note: The first call to this function, whether by your
+    /// code or SFML will result in a context switch.
+    ///
+    /// \return Maximum size allowed for textures, in pixels
+    ///
+    ////////////////////////////////////////////////////////////
+    static unsigned int getMaximumSize();
+
+private:
+
+    friend class RenderTexture;
+    friend class RenderTarget;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a valid image size according to hardware support
+    ///
+    /// This function checks whether the graphics driver supports
+    /// non power of two sizes or not, and adjusts the size
+    /// accordingly.
+    /// The returned size is greater than or equal to the original size.
+    ///
+    /// \param size size to convert
+    ///
+    /// \return Valid nearest size (greater than or equal to specified size)
+    ///
+    ////////////////////////////////////////////////////////////
+    static unsigned int getValidSize(unsigned int size);
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Vector2u     m_size;          ///< Public texture size
+    Vector2u     m_actualSize;    ///< Actual texture size (can be greater than public size because of padding)
+    unsigned int m_texture;       ///< Internal texture identifier
+    bool         m_isSmooth;      ///< Status of the smooth filter
+    bool         m_isRepeated;    ///< Is the texture in repeat mode?
+    mutable bool m_pixelsFlipped; ///< To work around the inconsistency in Y orientation
+    Uint64       m_cacheId;       ///< Unique number that identifies the texture to the render target's cache
+};
+
+} // namespace sf
+
+
+#endif // SFML_TEXTURE_HPP
+
+////////////////////////////////////////////////////////////
+/// \class sf::Texture
+/// \ingroup graphics
+///
+/// sf::Texture stores pixels that can be drawn, with a sprite
+/// for example. A texture lives in the graphics card memory,
+/// therefore it is very fast to draw a texture to a render target,
+/// or copy a render target to a texture (the graphics card can
+/// access both directly).
+///
+/// Being stored in the graphics card memory has some drawbacks.
+/// A texture cannot be manipulated as freely as a sf::Image,
+/// you need to prepare the pixels first and then upload them
+/// to the texture in a single operation (see Texture::update).
+///
+/// sf::Texture makes it easy to convert from/to sf::Image, but
+/// keep in mind that these calls require transfers between
+/// the graphics card and the central memory, therefore they are
+/// slow operations.
+///
+/// A texture can be loaded from an image, but also directly
+/// from a file/memory/stream. The necessary shortcuts are defined
+/// so that you don't need an image first for the most common cases.
+/// However, if you want to perform some modifications on the pixels
+/// before creating the final texture, you can load your file to a
+/// sf::Image, do whatever you need with the pixels, and then call
+/// Texture::loadFromImage.
+///
+/// Since they live in the graphics card memory, the pixels of a texture
+/// cannot be accessed without a slow copy first. And they cannot be
+/// accessed individually. Therefore, if you need to read the texture's
+/// pixels (like for pixel-perfect collisions), it is recommended to
+/// store the collision information separately, for example in an array
+/// of booleans.
+///
+/// Like sf::Image, sf::Texture can handle a unique internal
+/// representation of pixels, which is RGBA 32 bits. This means
+/// that a pixel must be composed of 8 bits red, green, blue and
+/// alpha channels -- just like a sf::Color.
+///
+/// Usage example:
+/// \code
+/// // This example shows the most common use of sf::Texture:
+/// // drawing a sprite
+///
+/// // Load a texture from a file
+/// sf::Texture texture;
+/// if (!texture.loadFromFile("texture.png"))
+///     return -1;
+///
+/// // Assign it to a sprite
+/// sf::Sprite sprite;
+/// sprite.setTexture(texture);
+///
+/// // Draw the textured sprite
+/// window.draw(sprite);
+/// \endcode
+///
+/// \code
+/// // This example shows another common use of sf::Texture:
+/// // streaming real-time data, like video frames
+///
+/// // Create an empty texture
+/// sf::Texture texture;
+/// if (!texture.create(640, 480))
+///     return -1;
+///
+/// // Create a sprite that will display the texture
+/// sf::Sprite sprite(texture);
+///
+/// while (...) // the main loop
+/// {
+///     ...
+///
+///     // update the texture
+///     sf::Uint8* pixels = ...; // get a fresh chunk of pixels (the next frame of a movie, for example)
+///     texture.update(pixels);
+///
+///     // draw it
+///     window.draw(sprite);
+///
+///     ...
+/// }
+///
+/// \endcode
+///
+/// Like sf::Shader that can be used as a raw OpenGL shader,
+/// sf::Texture can also be used directly as a raw texture for
+/// custom OpenGL geometry.
+/// \code
+/// sf::Texture::bind(&texture);
+/// ... render OpenGL geometry ...
+/// sf::Texture::bind(NULL);
+/// \endcode
+///
+/// \see sf::Sprite, sf::Image, sf::RenderTexture
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Transform.hpp b/dependencies64/sfml/include/SFML/Graphics/Transform.hpp
new file mode 100644 (file)
index 0000000..41155fb
--- /dev/null
@@ -0,0 +1,450 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TRANSFORM_HPP
+#define SFML_TRANSFORM_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Rect.hpp>
+#include <SFML/System/Vector2.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Define a 3x3 transform matrix
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API Transform
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Creates an identity transform (a transform that does nothing).
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct a transform from a 3x3 matrix
+    ///
+    /// \param a00 Element (0, 0) of the matrix
+    /// \param a01 Element (0, 1) of the matrix
+    /// \param a02 Element (0, 2) of the matrix
+    /// \param a10 Element (1, 0) of the matrix
+    /// \param a11 Element (1, 1) of the matrix
+    /// \param a12 Element (1, 2) of the matrix
+    /// \param a20 Element (2, 0) of the matrix
+    /// \param a21 Element (2, 1) of the matrix
+    /// \param a22 Element (2, 2) of the matrix
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform(float a00, float a01, float a02,
+              float a10, float a11, float a12,
+              float a20, float a21, float a22);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the transform as a 4x4 matrix
+    ///
+    /// This function returns a pointer to an array of 16 floats
+    /// containing the transform elements as a 4x4 matrix, which
+    /// is directly compatible with OpenGL functions.
+    ///
+    /// \code
+    /// sf::Transform transform = ...;
+    /// glLoadMatrixf(transform.getMatrix());
+    /// \endcode
+    ///
+    /// \return Pointer to a 4x4 matrix
+    ///
+    ////////////////////////////////////////////////////////////
+    const float* getMatrix() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the inverse of the transform
+    ///
+    /// If the inverse cannot be computed, an identity transform
+    /// is returned.
+    ///
+    /// \return A new transform which is the inverse of self
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform getInverse() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Transform a 2D point
+    ///
+    /// \param x X coordinate of the point to transform
+    /// \param y Y coordinate of the point to transform
+    ///
+    /// \return Transformed point
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2f transformPoint(float x, float y) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Transform a 2D point
+    ///
+    /// \param point Point to transform
+    ///
+    /// \return Transformed point
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2f transformPoint(const Vector2f& point) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Transform a rectangle
+    ///
+    /// Since SFML doesn't provide support for oriented rectangles,
+    /// the result of this function is always an axis-aligned
+    /// rectangle. Which means that if the transform contains a
+    /// rotation, the bounding rectangle of the transformed rectangle
+    /// is returned.
+    ///
+    /// \param rectangle Rectangle to transform
+    ///
+    /// \return Transformed rectangle
+    ///
+    ////////////////////////////////////////////////////////////
+    FloatRect transformRect(const FloatRect& rectangle) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with another one
+    ///
+    /// The result is a transform that is equivalent to applying
+    /// *this followed by \a transform. Mathematically, it is
+    /// equivalent to a matrix multiplication.
+    ///
+    /// \param transform Transform to combine with this transform
+    ///
+    /// \return Reference to *this
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& combine(const Transform& transform);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a translation
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.translate(100, 200).rotate(45);
+    /// \endcode
+    ///
+    /// \param x Offset to apply on X axis
+    /// \param y Offset to apply on Y axis
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see rotate, scale
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& translate(float x, float y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a translation
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.translate(sf::Vector2f(100, 200)).rotate(45);
+    /// \endcode
+    ///
+    /// \param offset Translation offset to apply
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see rotate, scale
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& translate(const Vector2f& offset);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a rotation
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.rotate(90).translate(50, 20);
+    /// \endcode
+    ///
+    /// \param angle Rotation angle, in degrees
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, scale
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& rotate(float angle);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a rotation
+    ///
+    /// The center of rotation is provided for convenience as a second
+    /// argument, so that you can build rotations around arbitrary points
+    /// more easily (and efficiently) than the usual
+    /// translate(-center).rotate(angle).translate(center).
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.rotate(90, 8, 3).translate(50, 20);
+    /// \endcode
+    ///
+    /// \param angle Rotation angle, in degrees
+    /// \param centerX X coordinate of the center of rotation
+    /// \param centerY Y coordinate of the center of rotation
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, scale
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& rotate(float angle, float centerX, float centerY);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a rotation
+    ///
+    /// The center of rotation is provided for convenience as a second
+    /// argument, so that you can build rotations around arbitrary points
+    /// more easily (and efficiently) than the usual
+    /// translate(-center).rotate(angle).translate(center).
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.rotate(90, sf::Vector2f(8, 3)).translate(sf::Vector2f(50, 20));
+    /// \endcode
+    ///
+    /// \param angle Rotation angle, in degrees
+    /// \param center Center of rotation
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, scale
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& rotate(float angle, const Vector2f& center);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a scaling
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.scale(2, 1).rotate(45);
+    /// \endcode
+    ///
+    /// \param scaleX Scaling factor on the X axis
+    /// \param scaleY Scaling factor on the Y axis
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, rotate
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& scale(float scaleX, float scaleY);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a scaling
+    ///
+    /// The center of scaling is provided for convenience as a second
+    /// argument, so that you can build scaling around arbitrary points
+    /// more easily (and efficiently) than the usual
+    /// translate(-center).scale(factors).translate(center).
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.scale(2, 1, 8, 3).rotate(45);
+    /// \endcode
+    ///
+    /// \param scaleX Scaling factor on X axis
+    /// \param scaleY Scaling factor on Y axis
+    /// \param centerX X coordinate of the center of scaling
+    /// \param centerY Y coordinate of the center of scaling
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, rotate
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& scale(float scaleX, float scaleY, float centerX, float centerY);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a scaling
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.scale(sf::Vector2f(2, 1)).rotate(45);
+    /// \endcode
+    ///
+    /// \param factors Scaling factors
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, rotate
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& scale(const Vector2f& factors);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Combine the current transform with a scaling
+    ///
+    /// The center of scaling is provided for convenience as a second
+    /// argument, so that you can build scaling around arbitrary points
+    /// more easily (and efficiently) than the usual
+    /// translate(-center).scale(factors).translate(center).
+    ///
+    /// This function returns a reference to *this, so that calls
+    /// can be chained.
+    /// \code
+    /// sf::Transform transform;
+    /// transform.scale(sf::Vector2f(2, 1), sf::Vector2f(8, 3)).rotate(45);
+    /// \endcode
+    ///
+    /// \param factors Scaling factors
+    /// \param center Center of scaling
+    ///
+    /// \return Reference to *this
+    ///
+    /// \see translate, rotate
+    ///
+    ////////////////////////////////////////////////////////////
+    Transform& scale(const Vector2f& factors, const Vector2f& center);
+
+    ////////////////////////////////////////////////////////////
+    // Static member data
+    ////////////////////////////////////////////////////////////
+    static const Transform Identity; ///< The identity transform (does nothing)
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    float m_matrix[16]; ///< 4x4 matrix defining the transformation
+};
+
+////////////////////////////////////////////////////////////
+/// \relates sf::Transform
+/// \brief Overload of binary operator * to combine two transforms
+///
+/// This call is equivalent to calling Transform(left).combine(right).
+///
+/// \param left Left operand (the first transform)
+/// \param right Right operand (the second transform)
+///
+/// \return New combined transform
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Transform operator *(const Transform& left, const Transform& right);
+
+////////////////////////////////////////////////////////////
+/// \relates sf::Transform
+/// \brief Overload of binary operator *= to combine two transforms
+///
+/// This call is equivalent to calling left.combine(right).
+///
+/// \param left Left operand (the first transform)
+/// \param right Right operand (the second transform)
+///
+/// \return The combined transform
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Transform& operator *=(Transform& left, const Transform& right);
+
+////////////////////////////////////////////////////////////
+/// \relates sf::Transform
+/// \brief Overload of binary operator * to transform a point
+///
+/// This call is equivalent to calling left.transformPoint(right).
+///
+/// \param left Left operand (the transform)
+/// \param right Right operand (the point to transform)
+///
+/// \return New transformed point
+///
+////////////////////////////////////////////////////////////
+SFML_GRAPHICS_API Vector2f operator *(const Transform& left, const Vector2f& right);
+
+} // namespace sf
+
+
+#endif // SFML_TRANSFORM_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Transform
+/// \ingroup graphics
+///
+/// A sf::Transform specifies how to translate, rotate, scale,
+/// shear, project, whatever things. In mathematical terms, it defines
+/// how to transform a coordinate system into another.
+///
+/// For example, if you apply a rotation transform to a sprite, the
+/// result will be a rotated sprite. And anything that is transformed
+/// by this rotation transform will be rotated the same way, according
+/// to its initial position.
+///
+/// Transforms are typically used for drawing. But they can also be
+/// used for any computation that requires to transform points between
+/// the local and global coordinate systems of an entity (like collision
+/// detection).
+///
+/// Example:
+/// \code
+/// // define a translation transform
+/// sf::Transform translation;
+/// translation.translate(20, 50);
+///
+/// // define a rotation transform
+/// sf::Transform rotation;
+/// rotation.rotate(45);
+///
+/// // combine them
+/// sf::Transform transform = translation * rotation;
+///
+/// // use the result to transform stuff...
+/// sf::Vector2f point = transform.transformPoint(10, 20);
+/// sf::FloatRect rect = transform.transformRect(sf::FloatRect(0, 0, 10, 100));
+/// \endcode
+///
+/// \see sf::Transformable, sf::RenderStates
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Transformable.hpp b/dependencies64/sfml/include/SFML/Graphics/Transformable.hpp
new file mode 100644 (file)
index 0000000..d1a92ae
--- /dev/null
@@ -0,0 +1,429 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TRANSFORMABLE_HPP
+#define SFML_TRANSFORMABLE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Transform.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Decomposed transform defined by a position, a rotation and a scale
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API Transformable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    Transformable();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Virtual destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~Transformable();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the position of the object
+    ///
+    /// This function completely overwrites the previous position.
+    /// See the move function to apply an offset based on the previous position instead.
+    /// The default position of a transformable object is (0, 0).
+    ///
+    /// \param x X coordinate of the new position
+    /// \param y Y coordinate of the new position
+    ///
+    /// \see move, getPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPosition(float x, float y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the position of the object
+    ///
+    /// This function completely overwrites the previous position.
+    /// See the move function to apply an offset based on the previous position instead.
+    /// The default position of a transformable object is (0, 0).
+    ///
+    /// \param position New position
+    ///
+    /// \see move, getPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPosition(const Vector2f& position);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the orientation of the object
+    ///
+    /// This function completely overwrites the previous rotation.
+    /// See the rotate function to add an angle based on the previous rotation instead.
+    /// The default rotation of a transformable object is 0.
+    ///
+    /// \param angle New rotation, in degrees
+    ///
+    /// \see rotate, getRotation
+    ///
+    ////////////////////////////////////////////////////////////
+    void setRotation(float angle);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the scale factors of the object
+    ///
+    /// This function completely overwrites the previous scale.
+    /// See the scale function to add a factor based on the previous scale instead.
+    /// The default scale of a transformable object is (1, 1).
+    ///
+    /// \param factorX New horizontal scale factor
+    /// \param factorY New vertical scale factor
+    ///
+    /// \see scale, getScale
+    ///
+    ////////////////////////////////////////////////////////////
+    void setScale(float factorX, float factorY);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the scale factors of the object
+    ///
+    /// This function completely overwrites the previous scale.
+    /// See the scale function to add a factor based on the previous scale instead.
+    /// The default scale of a transformable object is (1, 1).
+    ///
+    /// \param factors New scale factors
+    ///
+    /// \see scale, getScale
+    ///
+    ////////////////////////////////////////////////////////////
+    void setScale(const Vector2f& factors);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the local origin of the object
+    ///
+    /// The origin of an object defines the center point for
+    /// all transformations (position, scale, rotation).
+    /// The coordinates of this point must be relative to the
+    /// top-left corner of the object, and ignore all
+    /// transformations (position, scale, rotation).
+    /// The default origin of a transformable object is (0, 0).
+    ///
+    /// \param x X coordinate of the new origin
+    /// \param y Y coordinate of the new origin
+    ///
+    /// \see getOrigin
+    ///
+    ////////////////////////////////////////////////////////////
+    void setOrigin(float x, float y);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief set the local origin of the object
+    ///
+    /// The origin of an object defines the center point for
+    /// all transformations (position, scale, rotation).
+    /// The coordinates of this point must be relative to the
+    /// top-left corner of the object, and ignore all
+    /// transformations (position, scale, rotation).
+    /// The default origin of a transformable object is (0, 0).
+    ///
+    /// \param origin New origin
+    ///
+    /// \see getOrigin
+    ///
+    ////////////////////////////////////////////////////////////
+    void setOrigin(const Vector2f& origin);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief get the position of the object
+    ///
+    /// \return Current position
+    ///
+    /// \see setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    const Vector2f& getPosition() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief get the orientation of the object
+    ///
+    /// The rotation is always in the range [0, 360].
+    ///
+    /// \return Current rotation, in degrees
+    ///
+    /// \see setRotation
+    ///
+    ////////////////////////////////////////////////////////////
+    float getRotation() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief get the current scale of the object
+    ///
+    /// \return Current scale factors
+    ///
+    /// \see setScale
+    ///
+    ////////////////////////////////////////////////////////////
+    const Vector2f& getScale() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief get the local origin of the object
+    ///
+    /// \return Current origin
+    ///
+    /// \see setOrigin
+    ///
+    ////////////////////////////////////////////////////////////
+    const Vector2f& getOrigin() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Move the object by a given offset
+    ///
+    /// This function adds to the current position of the object,
+    /// unlike setPosition which overwrites it.
+    /// Thus, it is equivalent to the following code:
+    /// \code
+    /// sf::Vector2f pos = object.getPosition();
+    /// object.setPosition(pos.x + offsetX, pos.y + offsetY);
+    /// \endcode
+    ///
+    /// \param offsetX X offset
+    /// \param offsetY Y offset
+    ///
+    /// \see setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    void move(float offsetX, float offsetY);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Move the object by a given offset
+    ///
+    /// This function adds to the current position of the object,
+    /// unlike setPosition which overwrites it.
+    /// Thus, it is equivalent to the following code:
+    /// \code
+    /// object.setPosition(object.getPosition() + offset);
+    /// \endcode
+    ///
+    /// \param offset Offset
+    ///
+    /// \see setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    void move(const Vector2f& offset);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Rotate the object
+    ///
+    /// This function adds to the current rotation of the object,
+    /// unlike setRotation which overwrites it.
+    /// Thus, it is equivalent to the following code:
+    /// \code
+    /// object.setRotation(object.getRotation() + angle);
+    /// \endcode
+    ///
+    /// \param angle Angle of rotation, in degrees
+    ///
+    ////////////////////////////////////////////////////////////
+    void rotate(float angle);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Scale the object
+    ///
+    /// This function multiplies the current scale of the object,
+    /// unlike setScale which overwrites it.
+    /// Thus, it is equivalent to the following code:
+    /// \code
+    /// sf::Vector2f scale = object.getScale();
+    /// object.setScale(scale.x * factorX, scale.y * factorY);
+    /// \endcode
+    ///
+    /// \param factorX Horizontal scale factor
+    /// \param factorY Vertical scale factor
+    ///
+    /// \see setScale
+    ///
+    ////////////////////////////////////////////////////////////
+    void scale(float factorX, float factorY);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Scale the object
+    ///
+    /// This function multiplies the current scale of the object,
+    /// unlike setScale which overwrites it.
+    /// Thus, it is equivalent to the following code:
+    /// \code
+    /// sf::Vector2f scale = object.getScale();
+    /// object.setScale(scale.x * factor.x, scale.y * factor.y);
+    /// \endcode
+    ///
+    /// \param factor Scale factors
+    ///
+    /// \see setScale
+    ///
+    ////////////////////////////////////////////////////////////
+    void scale(const Vector2f& factor);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief get the combined transform of the object
+    ///
+    /// \return Transform combining the position/rotation/scale/origin of the object
+    ///
+    /// \see getInverseTransform
+    ///
+    ////////////////////////////////////////////////////////////
+    const Transform& getTransform() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief get the inverse of the combined transform of the object
+    ///
+    /// \return Inverse of the combined transformations applied to the object
+    ///
+    /// \see getTransform
+    ///
+    ////////////////////////////////////////////////////////////
+    const Transform& getInverseTransform() const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Vector2f          m_origin;                     ///< Origin of translation/rotation/scaling of the object
+    Vector2f          m_position;                   ///< Position of the object in the 2D world
+    float             m_rotation;                   ///< Orientation of the object, in degrees
+    Vector2f          m_scale;                      ///< Scale of the object
+    mutable Transform m_transform;                  ///< Combined transformation of the object
+    mutable bool      m_transformNeedUpdate;        ///< Does the transform need to be recomputed?
+    mutable Transform m_inverseTransform;           ///< Combined transformation of the object
+    mutable bool      m_inverseTransformNeedUpdate; ///< Does the transform need to be recomputed?
+};
+
+} // namespace sf
+
+
+#endif // SFML_TRANSFORMABLE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Transformable
+/// \ingroup graphics
+///
+/// This class is provided for convenience, on top of sf::Transform.
+///
+/// sf::Transform, as a low-level class, offers a great level of
+/// flexibility but it is not always convenient to manage. Indeed,
+/// one can easily combine any kind of operation, such as a translation
+/// followed by a rotation followed by a scaling, but once the result
+/// transform is built, there's no way to go backward and, let's say,
+/// change only the rotation without modifying the translation and scaling.
+/// The entire transform must be recomputed, which means that you
+/// need to retrieve the initial translation and scale factors as
+/// well, and combine them the same way you did before updating the
+/// rotation. This is a tedious operation, and it requires to store
+/// all the individual components of the final transform.
+///
+/// That's exactly what sf::Transformable was written for: it hides
+/// these variables and the composed transform behind an easy to use
+/// interface. You can set or get any of the individual components
+/// without worrying about the others. It also provides the composed
+/// transform (as a sf::Transform), and keeps it up-to-date.
+///
+/// In addition to the position, rotation and scale, sf::Transformable
+/// provides an "origin" component, which represents the local origin
+/// of the three other components. Let's take an example with a 10x10
+/// pixels sprite. By default, the sprite is positioned/rotated/scaled
+/// relatively to its top-left corner, because it is the local point
+/// (0, 0). But if we change the origin to be (5, 5), the sprite will
+/// be positioned/rotated/scaled around its center instead. And if
+/// we set the origin to (10, 10), it will be transformed around its
+/// bottom-right corner.
+///
+/// To keep the sf::Transformable class simple, there's only one
+/// origin for all the components. You cannot position the sprite
+/// relatively to its top-left corner while rotating it around its
+/// center, for example. To do such things, use sf::Transform directly.
+///
+/// sf::Transformable can be used as a base class. It is often
+/// combined with sf::Drawable -- that's what SFML's sprites,
+/// texts and shapes do.
+/// \code
+/// class MyEntity : public sf::Transformable, public sf::Drawable
+/// {
+///     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const
+///     {
+///         states.transform *= getTransform();
+///         target.draw(..., states);
+///     }
+/// };
+///
+/// MyEntity entity;
+/// entity.setPosition(10, 20);
+/// entity.setRotation(45);
+/// window.draw(entity);
+/// \endcode
+///
+/// It can also be used as a member, if you don't want to use
+/// its API directly (because you don't need all its functions,
+/// or you have different naming conventions for example).
+/// \code
+/// class MyEntity
+/// {
+/// public:
+///     void SetPosition(const MyVector& v)
+///     {
+///         myTransform.setPosition(v.x(), v.y());
+///     }
+///
+///     void Draw(sf::RenderTarget& target) const
+///     {
+///         target.draw(..., myTransform.getTransform());
+///     }
+///
+/// private:
+///     sf::Transformable myTransform;
+/// };
+/// \endcode
+///
+/// A note on coordinates and undistorted rendering: \n
+/// By default, SFML (or more exactly, OpenGL) may interpolate drawable objects  
+/// such as sprites or texts when rendering. While this allows transitions
+/// like slow movements or rotations to appear smoothly, it can lead to
+/// unwanted results in some cases, for example blurred or distorted objects.
+/// In order to render a sf::Drawable object pixel-perfectly, make sure
+/// the involved coordinates allow a 1:1 mapping of pixels in the window
+/// to texels (pixels in the texture). More specifically, this means:
+/// * The object's position, origin and scale have no fractional part
+/// * The object's and the view's rotation are a multiple of 90 degrees
+/// * The view's center and size have no fractional part
+/// 
+/// \see sf::Transform
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/Vertex.hpp b/dependencies64/sfml/include/SFML/Graphics/Vertex.hpp
new file mode 100644 (file)
index 0000000..cdd606b
--- /dev/null
@@ -0,0 +1,148 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_VERTEX_HPP
+#define SFML_VERTEX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Color.hpp>
+#include <SFML/System/Vector2.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Define a point with color and texture coordinates
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API Vertex
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    Vertex();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vertex from its position
+    ///
+    /// The vertex color is white and texture coordinates are (0, 0).
+    ///
+    /// \param thePosition Vertex position
+    ///
+    ////////////////////////////////////////////////////////////
+    Vertex(const Vector2f& thePosition);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vertex from its position and color
+    ///
+    /// The texture coordinates are (0, 0).
+    ///
+    /// \param thePosition Vertex position
+    /// \param theColor    Vertex color
+    ///
+    ////////////////////////////////////////////////////////////
+    Vertex(const Vector2f& thePosition, const Color& theColor);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vertex from its position and texture coordinates
+    ///
+    /// The vertex color is white.
+    ///
+    /// \param thePosition  Vertex position
+    /// \param theTexCoords Vertex texture coordinates
+    ///
+    ////////////////////////////////////////////////////////////
+    Vertex(const Vector2f& thePosition, const Vector2f& theTexCoords);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vertex from its position, color and texture coordinates
+    ///
+    /// \param thePosition  Vertex position
+    /// \param theColor     Vertex color
+    /// \param theTexCoords Vertex texture coordinates
+    ///
+    ////////////////////////////////////////////////////////////
+    Vertex(const Vector2f& thePosition, const Color& theColor, const Vector2f& theTexCoords);
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Vector2f  position;  ///< 2D position of the vertex
+    Color     color;     ///< Color of the vertex
+    Vector2f  texCoords; ///< Coordinates of the texture's pixel to map to the vertex
+};
+
+} // namespace sf
+
+
+#endif // SFML_VERTEX_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Vertex
+/// \ingroup graphics
+///
+/// A vertex is an improved point. It has a position and other
+/// extra attributes that will be used for drawing: in SFML,
+/// vertices also have a color and a pair of texture coordinates.
+///
+/// The vertex is the building block of drawing. Everything which
+/// is visible on screen is made of vertices. They are grouped
+/// as 2D primitives (triangles, quads, ...), and these primitives
+/// are grouped to create even more complex 2D entities such as
+/// sprites, texts, etc.
+///
+/// If you use the graphical entities of SFML (sprite, text, shape)
+/// you won't have to deal with vertices directly. But if you want
+/// to define your own 2D entities, such as tiled maps or particle
+/// systems, using vertices will allow you to get maximum performances.
+///
+/// Example:
+/// \code
+/// // define a 100x100 square, red, with a 10x10 texture mapped on it
+/// sf::Vertex vertices[] =
+/// {
+///     sf::Vertex(sf::Vector2f(  0,   0), sf::Color::Red, sf::Vector2f( 0,  0)),
+///     sf::Vertex(sf::Vector2f(  0, 100), sf::Color::Red, sf::Vector2f( 0, 10)),
+///     sf::Vertex(sf::Vector2f(100, 100), sf::Color::Red, sf::Vector2f(10, 10)),
+///     sf::Vertex(sf::Vector2f(100,   0), sf::Color::Red, sf::Vector2f(10,  0))
+/// };
+///
+/// // draw it
+/// window.draw(vertices, 4, sf::Quads);
+/// \endcode
+///
+/// Note: although texture coordinates are supposed to be an integer
+/// amount of pixels, their type is float because of some buggy graphics
+/// drivers that are not able to process integer coordinates correctly.
+///
+/// \see sf::VertexArray
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Graphics/VertexArray.hpp b/dependencies64/sfml/include/SFML/Graphics/VertexArray.hpp
new file mode 100644 (file)
index 0000000..6faca07
--- /dev/null
@@ -0,0 +1,223 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_VERTEXARRAY_HPP
+#define SFML_VERTEXARRAY_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Graphics/Export.hpp>
+#include <SFML/Graphics/Vertex.hpp>
+#include <SFML/Graphics/PrimitiveType.hpp>
+#include <SFML/Graphics/Rect.hpp>
+#include <SFML/Graphics/Drawable.hpp>
+#include <vector>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Define a set of one or more 2D primitives
+///
+////////////////////////////////////////////////////////////
+class SFML_GRAPHICS_API VertexArray : public Drawable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Creates an empty vertex array.
+    ///
+    ////////////////////////////////////////////////////////////
+    VertexArray();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vertex array with a type and an initial number of vertices
+    ///
+    /// \param type        Type of primitives
+    /// \param vertexCount Initial number of vertices in the array
+    ///
+    ////////////////////////////////////////////////////////////
+    explicit VertexArray(PrimitiveType type, unsigned int vertexCount = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the vertex count
+    ///
+    /// \return Number of vertices in the array
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned int getVertexCount() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a read-write access to a vertex by its index
+    ///
+    /// This function doesn't check \a index, it must be in range
+    /// [0, getVertexCount() - 1]. The behavior is undefined
+    /// otherwise.
+    ///
+    /// \param index Index of the vertex to get
+    ///
+    /// \return Reference to the index-th vertex
+    ///
+    /// \see getVertexCount
+    ///
+    ////////////////////////////////////////////////////////////
+    Vertex& operator [](unsigned int index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a read-only access to a vertex by its index
+    ///
+    /// This function doesn't check \a index, it must be in range
+    /// [0, getVertexCount() - 1]. The behavior is undefined
+    /// otherwise.
+    ///
+    /// \param index Index of the vertex to get
+    ///
+    /// \return Const reference to the index-th vertex
+    ///
+    /// \see getVertexCount
+    ///
+    ////////////////////////////////////////////////////////////
+    const Vertex& operator [](unsigned int index) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Clear the vertex array
+    ///
+    /// This function removes all the vertices from the array.
+    /// It doesn't deallocate the corresponding memory, so that
+    /// adding new vertices after clearing doesn't involve
+    /// reallocating all the memory.
+    ///
+    ////////////////////////////////////////////////////////////
+    void clear();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Resize the vertex array
+    ///
+    /// If \a vertexCount is greater than the current size, the previous
+    /// vertices are kept and new (default-constructed) vertices are
+    /// added.
+    /// If \a vertexCount is less than the current size, existing vertices
+    /// are removed from the array.
+    ///
+    /// \param vertexCount New size of the array (number of vertices)
+    ///
+    ////////////////////////////////////////////////////////////
+    void resize(unsigned int vertexCount);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Add a vertex to the array
+    ///
+    /// \param vertex Vertex to add
+    ///
+    ////////////////////////////////////////////////////////////
+    void append(const Vertex& vertex);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the type of primitives to draw
+    ///
+    /// This function defines how the vertices must be interpreted
+    /// when it's time to draw them:
+    /// \li As points
+    /// \li As lines
+    /// \li As triangles
+    /// \li As quads
+    /// The default primitive type is sf::Points.
+    ///
+    /// \param type Type of primitive
+    ///
+    ////////////////////////////////////////////////////////////
+    void setPrimitiveType(PrimitiveType type);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the type of primitives drawn by the vertex array
+    ///
+    /// \return Primitive type
+    ///
+    ////////////////////////////////////////////////////////////
+    PrimitiveType getPrimitiveType() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Compute the bounding rectangle of the vertex array
+    ///
+    /// This function returns the axis-aligned rectangle that
+    /// contains all the vertices of the array.
+    ///
+    /// \return Bounding rectangle of the vertex array
+    ///
+    ////////////////////////////////////////////////////////////
+    FloatRect getBounds() const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Draw the vertex array to a render target
+    ///
+    /// \param target Render target to draw to
+    /// \param states Current render states
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual void draw(RenderTarget& target, RenderStates states) const;
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    std::vector<Vertex> m_vertices;      ///< Vertices contained in the array
+    PrimitiveType       m_primitiveType; ///< Type of primitives to draw
+};
+
+} // namespace sf
+
+
+#endif // SFML_VERTEXARRAY_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::VertexArray
+/// \ingroup graphics
+///
+/// sf::VertexArray is a very simple wrapper around a dynamic
+/// array of vertices and a primitives type.
+///
+/// It inherits sf::Drawable, but unlike other drawables it
+/// is not transformable.
+///
+/// Example:
+/// \code
+/// sf::VertexArray lines(sf::LinesStrip, 4);
+/// lines[0].position = sf::Vector2f(10, 0);
+/// lines[1].position = sf::Vector2f(20, 0);
+/// lines[2].position = sf::Vector2f(30, 5);
+/// lines[3].position = sf::Vector2f(40, 2);
+///
+/// window.draw(lines);
+/// \endcode
+///
+/// \see sf::Vertex
+///
+////////////////////////////////////////////////////////////
index b2765ed411437e9877b27561b31e1c42434ff3cd..f4ff818fe24dd77f129508ab1578c0a2b4d22efc 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/Graphics/Export.hpp>
 #include <SFML/Graphics/Rect.hpp>
-#include <SFML/Graphics/Matrix3.hpp>
+#include <SFML/Graphics/Transform.hpp>
 #include <SFML/System/Vector2.hpp>
 
 
 namespace sf
 {
-class RenderTarget;
-
 ////////////////////////////////////////////////////////////
-/// This class defines a view (position, size, etc.) ;
-/// you can consider it as a 2D camera
+/// \brief 2D camera that defines what region is shown on screen
+///
 ////////////////////////////////////////////////////////////
-class SFML_API View
+class SFML_GRAPHICS_API View
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Construct the view from a rectangle
+    /// \brief Default constructor
     ///
-    /// \param ViewRect : Rectangle defining the position and size of the view (1000x1000 by default)
+    /// This constructor creates a default view of (0, 0, 1000, 1000)
     ///
     ////////////////////////////////////////////////////////////
-    explicit View(const FloatRect& ViewRect = FloatRect(0, 0, 1000, 1000));
+    View();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the view from its center and half-size
+    /// \brief Construct the view from a rectangle
     ///
-    /// \param Center :   Center of the view
-    /// \param HalfSize : Half-size of the view (from center to corner)
+    /// \param rectangle Rectangle defining the zone to display
     ///
     ////////////////////////////////////////////////////////////
-    View(const sf::Vector2f& Center, const sf::Vector2f& HalfSize);
+    explicit View(const FloatRect& rectangle);
 
     ////////////////////////////////////////////////////////////
-    /// Change the center of the view (take 2 values)
+    /// \brief Construct the view from its center and size
+    ///
+    /// \param center Center of the zone to display
+    /// \param size   Size of zone to display
+    ///
+    ////////////////////////////////////////////////////////////
+    View(const Vector2f& center, const Vector2f& size);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the center of the view
+    ///
+    /// \param x X coordinate of the new center
+    /// \param y Y coordinate of the new center
     ///
-    /// \param X : X coordinate of the new center
-    /// \param Y : Y coordinate of the new center
+    /// \see setSize, getCenter
     ///
     ////////////////////////////////////////////////////////////
-    void SetCenter(float X, float Y);
+    void setCenter(float x, float y);
 
     ////////////////////////////////////////////////////////////
-    /// Change the center of the view (take a vector)
+    /// \brief Set the center of the view
     ///
-    /// \param Center : New center
+    /// \param center New center
+    ///
+    /// \see setSize, getCenter
     ///
     ////////////////////////////////////////////////////////////
-    void SetCenter(const sf::Vector2f& Center);
+    void setCenter(const Vector2f& center);
 
     ////////////////////////////////////////////////////////////
-    /// Change the half-size of the view (take 2 values)
+    /// \brief Set the size of the view
+    ///
+    /// \param width  New width of the view
+    /// \param height New height of the view
     ///
-    /// \param HalfWidth :  New half-width
-    /// \param HalfHeight : New half-height
+    /// \see setCenter, getCenter
     ///
     ////////////////////////////////////////////////////////////
-    void SetHalfSize(float HalfWidth, float HalfHeight);
+    void setSize(float width, float height);
 
     ////////////////////////////////////////////////////////////
-    /// Change the half-size of the view (take a vector)
+    /// \brief Set the size of the view
     ///
-    /// \param HalfSize : New half-size
+    /// \param size New size
+    ///
+    /// \see setCenter, getCenter
     ///
     ////////////////////////////////////////////////////////////
-    void SetHalfSize(const sf::Vector2f& HalfSize);
+    void setSize(const Vector2f& size);
 
     ////////////////////////////////////////////////////////////
-    /// Rebuild the view from a rectangle
+    /// \brief Set the orientation of the view
+    ///
+    /// The default rotation of a view is 0 degree.
     ///
-    /// \param ViewRect : Rectangle defining the position and size of the view
+    /// \param angle New angle, in degrees
+    ///
+    /// \see getRotation
     ///
     ////////////////////////////////////////////////////////////
-    void SetFromRect(const FloatRect& ViewRect);
+    void setRotation(float angle);
 
     ////////////////////////////////////////////////////////////
-    /// Get the center of the view
+    /// \brief Set the target viewport
+    ///
+    /// The viewport is the rectangle into which the contents of the
+    /// view are displayed, expressed as a factor (between 0 and 1)
+    /// of the size of the RenderTarget to which the view is applied.
+    /// For example, a view which takes the left side of the target would
+    /// be defined with View.setViewport(sf::FloatRect(0, 0, 0.5, 1)).
+    /// By default, a view has a viewport which covers the entire target.
+    ///
+    /// \param viewport New viewport rectangle
+    ///
+    /// \see getViewport
+    ///
+    ////////////////////////////////////////////////////////////
+    void setViewport(const FloatRect& viewport);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Reset the view to the given rectangle
+    ///
+    /// Note that this function resets the rotation angle to 0.
+    ///
+    /// \param rectangle Rectangle defining the zone to display
+    ///
+    /// \see setCenter, setSize, setRotation
+    ///
+    ////////////////////////////////////////////////////////////
+    void reset(const FloatRect& rectangle);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the center of the view
     ///
     /// \return Center of the view
     ///
+    /// \see getSize, setCenter
+    ///
     ////////////////////////////////////////////////////////////
-    const sf::Vector2f& GetCenter() const;
+    const Vector2f& getCenter() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the half-size of the view
+    /// \brief Get the size of the view
     ///
-    /// \return Half-size of the view
+    /// \return Size of the view
+    ///
+    /// \see getCenter, setSize
     ///
     ////////////////////////////////////////////////////////////
-    const sf::Vector2f& GetHalfSize() const;
+    const Vector2f& getSize() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the bounding rectangle of the view
+    /// \brief Get the current orientation of the view
+    ///
+    /// \return Rotation angle of the view, in degrees
     ///
-    /// \return Bounding rectangle of the view
+    /// \see setRotation
     ///
     ////////////////////////////////////////////////////////////
-    const sf::FloatRect& GetRect() const;
+    float getRotation() const;
 
     ////////////////////////////////////////////////////////////
-    /// Move the view (take 2 values)
+    /// \brief Get the target viewport rectangle of the view
     ///
-    /// \param OffsetX : Offset to move the view, on X axis
-    /// \param OffsetY : Offset to move the view, on Y axis
+    /// \return Viewport rectangle, expressed as a factor of the target size
+    ///
+    /// \see setViewport
     ///
     ////////////////////////////////////////////////////////////
-    void Move(float OffsetX, float OffsetY);
+    const FloatRect& getViewport() const;
 
     ////////////////////////////////////////////////////////////
-    /// Move the view (take a vector)
+    /// \brief Move the view relatively to its current position
+    ///
+    /// \param offsetX X coordinate of the move offset
+    /// \param offsetY Y coordinate of the move offset
     ///
-    /// \param Offset : Offset to move the view
+    /// \see setCenter, rotate, zoom
     ///
     ////////////////////////////////////////////////////////////
-    void Move(const sf::Vector2f& Offset);
+    void move(float offsetX, float offsetY);
 
     ////////////////////////////////////////////////////////////
-    /// Resize the view rectangle to simulate a zoom / unzoom effect
+    /// \brief Move the view relatively to its current position
     ///
-    /// \param Factor : Zoom factor to apply, relative to the current zoom
+    /// \param offset Move offset
+    ///
+    /// \see setCenter, rotate, zoom
     ///
     ////////////////////////////////////////////////////////////
-    void Zoom(float Factor);
+    void move(const Vector2f& offset);
 
-private :
+    ////////////////////////////////////////////////////////////
+    /// \brief Rotate the view relatively to its current orientation
+    ///
+    /// \param angle Angle to rotate, in degrees
+    ///
+    /// \see setRotation, move, zoom
+    ///
+    ////////////////////////////////////////////////////////////
+    void rotate(float angle);
 
-    friend class RenderTarget;
+    ////////////////////////////////////////////////////////////
+    /// \brief Resize the view rectangle relatively to its current size
+    ///
+    /// Resizing the view simulates a zoom, as the zone displayed on
+    /// screen grows or shrinks.
+    /// \a factor is a multiplier:
+    /// \li 1 keeps the size unchanged
+    /// \li > 1 makes the view bigger (objects appear smaller)
+    /// \li < 1 makes the view smaller (objects appear bigger)
+    ///
+    /// \param factor Zoom factor to apply
+    ///
+    /// \see setSize, move, rotate
+    ///
+    ////////////////////////////////////////////////////////////
+    void zoom(float factor);
 
     ////////////////////////////////////////////////////////////
-    /// Get the projection matrix of the view
+    /// \brief Get the projection transform of the view
+    ///
+    /// This function is meant for internal use only.
     ///
-    /// \return Projection matrix containing the view settings
+    /// \return Projection transform defining the view
+    ///
+    /// \see getInverseTransform
     ///
     ////////////////////////////////////////////////////////////
-    const Matrix3& GetMatrix() const;
+    const Transform& getTransform() const;
 
     ////////////////////////////////////////////////////////////
-    /// Recompute the view rectangle and the projection matrix
+    /// \brief Get the inverse projection transform of the view
+    ///
+    /// This function is meant for internal use only.
+    ///
+    /// \return Inverse of the projection transform defining the view
+    ///
+    /// \see getTransform
     ///
     ////////////////////////////////////////////////////////////
-    void RecomputeMatrix();
+    const Transform& getInverseTransform() const;
+
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    sf::Vector2f myCenter;     ///< Center of the view
-    sf::Vector2f myHalfSize;   ///< Half-size of the view
-    FloatRect    myRect;       ///< Rectangle defining the bounds of the view
-    Matrix3      myMatrix;     ///< Precomputed projection matrix corresponding to the view
-    bool         myNeedUpdate; ///< Internal state telling if the matrix needs to be updated
+    Vector2f          m_center;              ///< Center of the view, in scene coordinates
+    Vector2f          m_size;                ///< Size of the view, in scene coordinates
+    float             m_rotation;            ///< Angle of rotation of the view rectangle, in degrees
+    FloatRect         m_viewport;            ///< Viewport rectangle, expressed as a factor of the render-target's size
+    mutable Transform m_transform;           ///< Precomputed projection transform corresponding to the view
+    mutable Transform m_inverseTransform;    ///< Precomputed inverse projection transform corresponding to the view
+    mutable bool      m_transformUpdated;    ///< Internal state telling if the transform needs to be updated
+    mutable bool      m_invTransformUpdated; ///< Internal state telling if the inverse transform needs to be updated
 };
 
 } // namespace sf
 
 
 #endif // SFML_VIEW_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::View
+/// \ingroup graphics
+///
+/// sf::View defines a camera in the 2D scene. This is a
+/// very powerful concept: you can scroll, rotate or zoom
+/// the entire scene without altering the way that your
+/// drawable objects are drawn.
+///
+/// A view is composed of a source rectangle, which defines
+/// what part of the 2D scene is shown, and a target viewport,
+/// which defines where the contents of the source rectangle
+/// will be displayed on the render target (window or texture).
+///
+/// The viewport allows to map the scene to a custom part
+/// of the render target, and can be used for split-screen
+/// or for displaying a minimap, for example. If the source
+/// rectangle has not the same size as the viewport, its
+/// contents will be stretched to fit in.
+///
+/// To apply a view, you have to assign it to the render target.
+/// Then, every objects drawn in this render target will be
+/// affected by the view until you use another view.
+///
+/// Usage example:
+/// \code
+/// sf::RenderWindow window;
+/// sf::View view;
+/// 
+/// // Initialize the view to a rectangle located at (100, 100) and with a size of 400x200
+/// view.reset(sf::FloatRect(100, 100, 400, 200));
+///
+/// // Rotate it by 45 degrees
+/// view.rotate(45);
+///
+/// // Set its target viewport to be half of the window
+/// view.setViewport(sf::FloatRect(0.f, 0.f, 0.5f, 1.f));
+///
+/// // Apply it
+/// window.setView(view);
+///
+/// // Render stuff
+/// window.draw(someSprite);
+///
+/// // Set the default view back
+/// window.setView(window.getDefaultView());
+///
+/// // Render stuff not affected by the view
+/// window.draw(someText);
+/// \endcode
+///
+/// See also the note on coordinates and undistorted rendering in sf::Transformable.
+///
+/// \see sf::RenderWindow, sf::RenderTexture
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Main.hpp b/dependencies64/sfml/include/SFML/Main.hpp
new file mode 100644 (file)
index 0000000..254ad7d
--- /dev/null
@@ -0,0 +1,43 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_MAIN_HPP
+#define SFML_MAIN_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+#if defined(SFML_SYSTEM_IOS)
+
+    // On iOS, we have no choice but to have our own main,
+    // so we need to rename the user one and call it later
+    #define main sfmlMain
+
+#endif
+
+
+#endif // SFML_MAIN_HPP
index b0ca47d2b123f1c009671cf48af6aa8907062168..e5e5d067481f4337d79ebb6bd191e9fcc7d55691 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 #include <SFML/System.hpp>
 #include <SFML/Network/Ftp.hpp>
 #include <SFML/Network/Http.hpp>
-#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/IpAddress.hpp>
 #include <SFML/Network/Packet.hpp>
-#include <SFML/Network/Selector.hpp>
-#include <SFML/Network/SocketTCP.hpp>
-#include <SFML/Network/SocketUDP.hpp>
+#include <SFML/Network/SocketSelector.hpp>
+#include <SFML/Network/TcpListener.hpp>
+#include <SFML/Network/TcpSocket.hpp>
+#include <SFML/Network/UdpSocket.hpp>
 
 
 #endif // SFML_NETWORK_HPP
+
+////////////////////////////////////////////////////////////
+/// \defgroup network Network module
+///
+/// Socket-based communication, utilities and higher-level
+/// network protocols (HTTP, FTP).
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/Export.hpp b/dependencies64/sfml/include/SFML/Network/Export.hpp
new file mode 100644 (file)
index 0000000..030b8d5
--- /dev/null
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_NETWORK_EXPORT_HPP
+#define SFML_NETWORK_EXPORT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_NETWORK_EXPORTS)
+
+    #define SFML_NETWORK_API SFML_API_EXPORT
+
+#else
+
+    #define SFML_NETWORK_API SFML_API_IMPORT
+
+#endif
+
+
+#endif // SFML_NETWORK_EXPORT_HPP
diff --git a/dependencies64/sfml/include/SFML/Network/Ftp.hpp b/dependencies64/sfml/include/SFML/Network/Ftp.hpp
new file mode 100644 (file)
index 0000000..4dd242b
--- /dev/null
@@ -0,0 +1,608 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_FTP_HPP
+#define SFML_FTP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/Network/TcpSocket.hpp>
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/System/Time.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+class IpAddress;
+
+////////////////////////////////////////////////////////////
+/// \brief A FTP client
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API Ftp : NonCopyable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enumeration of transfer modes
+    ///
+    ////////////////////////////////////////////////////////////
+    enum TransferMode
+    {
+        Binary, ///< Binary mode (file is transfered as a sequence of bytes)
+        Ascii,  ///< Text mode using ASCII encoding
+        Ebcdic  ///< Text mode using EBCDIC encoding
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Define a FTP response
+    ///
+    ////////////////////////////////////////////////////////////
+    class SFML_NETWORK_API Response
+    {
+    public:
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Status codes possibly returned by a FTP response
+        ///
+        ////////////////////////////////////////////////////////////
+        enum Status
+        {
+            // 1xx: the requested action is being initiated,
+            // expect another reply before proceeding with a new command
+            RestartMarkerReply          = 110, ///< Restart marker reply
+            ServiceReadySoon            = 120, ///< Service ready in N minutes
+            DataConnectionAlreadyOpened = 125, ///< Data connection already opened, transfer starting
+            OpeningDataConnection       = 150, ///< File status ok, about to open data connection
+
+            // 2xx: the requested action has been successfully completed
+            Ok                    = 200, ///< Command ok
+            PointlessCommand      = 202, ///< Command not implemented
+            SystemStatus          = 211, ///< System status, or system help reply
+            DirectoryStatus       = 212, ///< Directory status
+            FileStatus            = 213, ///< File status
+            HelpMessage           = 214, ///< Help message
+            SystemType            = 215, ///< NAME system type, where NAME is an official system name from the list in the Assigned Numbers document
+            ServiceReady          = 220, ///< Service ready for new user
+            ClosingConnection     = 221, ///< Service closing control connection
+            DataConnectionOpened  = 225, ///< Data connection open, no transfer in progress
+            ClosingDataConnection = 226, ///< Closing data connection, requested file action successful
+            EnteringPassiveMode   = 227, ///< Entering passive mode
+            LoggedIn              = 230, ///< User logged in, proceed. Logged out if appropriate
+            FileActionOk          = 250, ///< Requested file action ok
+            DirectoryOk           = 257, ///< PATHNAME created
+
+            // 3xx: the command has been accepted, but the requested action
+            // is dormant, pending receipt of further information
+            NeedPassword       = 331, ///< User name ok, need password
+            NeedAccountToLogIn = 332, ///< Need account for login
+            NeedInformation    = 350, ///< Requested file action pending further information
+
+            // 4xx: the command was not accepted and the requested action did not take place,
+            // but the error condition is temporary and the action may be requested again
+            ServiceUnavailable        = 421, ///< Service not available, closing control connection
+            DataConnectionUnavailable = 425, ///< Can't open data connection
+            TransferAborted           = 426, ///< Connection closed, transfer aborted
+            FileActionAborted         = 450, ///< Requested file action not taken
+            LocalError                = 451, ///< Requested action aborted, local error in processing
+            InsufficientStorageSpace  = 452, ///< Requested action not taken; insufficient storage space in system, file unavailable
+
+            // 5xx: the command was not accepted and
+            // the requested action did not take place
+            CommandUnknown          = 500, ///< Syntax error, command unrecognized
+            ParametersUnknown       = 501, ///< Syntax error in parameters or arguments
+            CommandNotImplemented   = 502, ///< Command not implemented
+            BadCommandSequence      = 503, ///< Bad sequence of commands
+            ParameterNotImplemented = 504, ///< Command not implemented for that parameter
+            NotLoggedIn             = 530, ///< Not logged in
+            NeedAccountToStore      = 532, ///< Need account for storing files
+            FileUnavailable         = 550, ///< Requested action not taken, file unavailable
+            PageTypeUnknown         = 551, ///< Requested action aborted, page type unknown
+            NotEnoughMemory         = 552, ///< Requested file action aborted, exceeded storage allocation
+            FilenameNotAllowed      = 553, ///< Requested action not taken, file name not allowed
+
+            // 10xx: SFML custom codes
+            InvalidResponse  = 1000, ///< Response is not a valid FTP one
+            ConnectionFailed = 1001, ///< Connection with server failed
+            ConnectionClosed = 1002, ///< Connection with server closed
+            InvalidFile      = 1003  ///< Invalid file to upload / download
+        };
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Default constructor
+        ///
+        /// This constructor is used by the FTP client to build
+        /// the response.
+        ///
+        /// \param code    Response status code
+        /// \param message Response message
+        ///
+        ////////////////////////////////////////////////////////////
+        explicit Response(Status code = InvalidResponse, const std::string& message = "");
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Check if the status code means a success
+        ///
+        /// This function is defined for convenience, it is
+        /// equivalent to testing if the status code is < 400.
+        ///
+        /// \return True if the status is a success, false if it is a failure
+        ///
+        ////////////////////////////////////////////////////////////
+        bool isOk() const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the status code of the response
+        ///
+        /// \return Status code
+        ///
+        ////////////////////////////////////////////////////////////
+        Status getStatus() const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the full message contained in the response
+        ///
+        /// \return The response message
+        ///
+        ////////////////////////////////////////////////////////////
+        const std::string& getMessage() const;
+
+    private:
+
+        ////////////////////////////////////////////////////////////
+        // Member data
+        ////////////////////////////////////////////////////////////
+        Status      m_status;  ///< Status code returned from the server
+        std::string m_message; ///< Last message received from the server
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Specialization of FTP response returning a directory
+    ///
+    ////////////////////////////////////////////////////////////
+    class SFML_NETWORK_API DirectoryResponse : public Response
+    {
+    public:
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Default constructor
+        ///
+        /// \param response Source response
+        ///
+        ////////////////////////////////////////////////////////////
+        DirectoryResponse(const Response& response);
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the directory returned in the response
+        ///
+        /// \return Directory name
+        ///
+        ////////////////////////////////////////////////////////////
+        const std::string& getDirectory() const;
+
+    private:
+
+        ////////////////////////////////////////////////////////////
+        // Member data
+        ////////////////////////////////////////////////////////////
+        std::string m_directory; ///< Directory extracted from the response message
+    };
+
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Specialization of FTP response returning a
+    ///        filename listing
+    ////////////////////////////////////////////////////////////
+    class SFML_NETWORK_API ListingResponse : public Response
+    {
+    public:
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Default constructor
+        ///
+        /// \param response  Source response
+        /// \param data      Data containing the raw listing
+        ///
+        ////////////////////////////////////////////////////////////
+        ListingResponse(const Response& response, const std::string& data);
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Return the array of directory/file names
+        ///
+        /// \return Array containing the requested listing
+        ///
+        ////////////////////////////////////////////////////////////
+        const std::vector<std::string>& getListing() const;
+
+    private:
+
+        ////////////////////////////////////////////////////////////
+        // Member data
+        ////////////////////////////////////////////////////////////
+        std::vector<std::string> m_listing; ///< Directory/file names extracted from the data
+    };
+
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    /// Automatically closes the connection with the server if
+    /// it is still opened.
+    ///
+    ////////////////////////////////////////////////////////////
+    ~Ftp();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Connect to the specified FTP server
+    ///
+    /// The port has a default value of 21, which is the standard
+    /// port used by the FTP protocol. You shouldn't use a different
+    /// value, unless you really know what you do.
+    /// This function tries to connect to the server so it may take
+    /// a while to complete, especially if the server is not
+    /// reachable. To avoid blocking your application for too long,
+    /// you can use a timeout. The default value, Time::Zero, means that the
+    /// system timeout will be used (which is usually pretty long).
+    ///
+    /// \param server  Name or address of the FTP server to connect to
+    /// \param port    Port used for the connection
+    /// \param timeout Maximum time to wait
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see disconnect
+    ///
+    ////////////////////////////////////////////////////////////
+    Response connect(const IpAddress& server, unsigned short port = 21, Time timeout = Time::Zero);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Close the connection with the server
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see connect
+    ///
+    ////////////////////////////////////////////////////////////
+    Response disconnect();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Log in using an anonymous account
+    ///
+    /// Logging in is mandatory after connecting to the server.
+    /// Users that are not logged in cannot perform any operation.
+    ///
+    /// \return Server response to the request
+    ///
+    ////////////////////////////////////////////////////////////
+    Response login();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Log in using a username and a password
+    ///
+    /// Logging in is mandatory after connecting to the server.
+    /// Users that are not logged in cannot perform any operation.
+    ///
+    /// \param name     User name
+    /// \param password Password
+    ///
+    /// \return Server response to the request
+    ///
+    ////////////////////////////////////////////////////////////
+    Response login(const std::string& name, const std::string& password);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send a null command to keep the connection alive
+    ///
+    /// This command is useful because the server may close the
+    /// connection automatically if no command is sent.
+    ///
+    /// \return Server response to the request
+    ///
+    ////////////////////////////////////////////////////////////
+    Response keepAlive();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current working directory
+    ///
+    /// The working directory is the root path for subsequent
+    /// operations involving directories and/or filenames.
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see getDirectoryListing, changeDirectory, parentDirectory
+    ///
+    ////////////////////////////////////////////////////////////
+    DirectoryResponse getWorkingDirectory();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the contents of the given directory
+    ///
+    /// This function retrieves the sub-directories and files
+    /// contained in the given directory. It is not recursive.
+    /// The \a directory parameter is relative to the current
+    /// working directory.
+    ///
+    /// \param directory Directory to list
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see getWorkingDirectory, changeDirectory, parentDirectory
+    ///
+    ////////////////////////////////////////////////////////////
+    ListingResponse getDirectoryListing(const std::string& directory = "");
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change the current working directory
+    ///
+    /// The new directory must be relative to the current one.
+    ///
+    /// \param directory New working directory
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see getWorkingDirectory, getDirectoryListing, parentDirectory
+    ///
+    ////////////////////////////////////////////////////////////
+    Response changeDirectory(const std::string& directory);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Go to the parent directory of the current one
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see getWorkingDirectory, getDirectoryListing, changeDirectory
+    ///
+    ////////////////////////////////////////////////////////////
+    Response parentDirectory();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create a new directory
+    ///
+    /// The new directory is created as a child of the current
+    /// working directory.
+    ///
+    /// \param name Name of the directory to create
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see deleteDirectory
+    ///
+    ////////////////////////////////////////////////////////////
+    Response createDirectory(const std::string& name);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Remove an existing directory
+    ///
+    /// The directory to remove must be relative to the
+    /// current working directory.
+    /// Use this function with caution, the directory will
+    /// be removed permanently!
+    ///
+    /// \param name Name of the directory to remove
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see createDirectory
+    ///
+    ////////////////////////////////////////////////////////////
+    Response deleteDirectory(const std::string& name);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Rename an existing file
+    ///
+    /// The filenames must be relative to the current working
+    /// directory.
+    ///
+    /// \param file    File to rename
+    /// \param newName New name of the file
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see deleteFile
+    ///
+    ////////////////////////////////////////////////////////////
+    Response renameFile(const std::string& file, const std::string& newName);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Remove an existing file
+    ///
+    /// The file name must be relative to the current working
+    /// directory.
+    /// Use this function with caution, the file will be
+    /// removed permanently!
+    ///
+    /// \param name File to remove
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see renameFile
+    ///
+    ////////////////////////////////////////////////////////////
+    Response deleteFile(const std::string& name);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Download a file from the server
+    ///
+    /// The filename of the distant file is relative to the
+    /// current working directory of the server, and the local
+    /// destination path is relative to the current directory
+    /// of your application.
+    /// If a file with the same filename as the distant file
+    /// already exists in the local destination path, it will
+    /// be overwritten.
+    ///
+    /// \param remoteFile Filename of the distant file to download
+    /// \param localPath  The directory in which to put the file on the local computer
+    /// \param mode       Transfer mode
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see upload
+    ///
+    ////////////////////////////////////////////////////////////
+    Response download(const std::string& remoteFile, const std::string& localPath, TransferMode mode = Binary);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Upload a file to the server
+    ///
+    /// The name of the local file is relative to the current
+    /// working directory of your application, and the
+    /// remote path is relative to the current directory of the
+    /// FTP server.
+    ///
+    /// \param localFile  Path of the local file to upload
+    /// \param remotePath The directory in which to put the file on the server
+    /// \param mode       Transfer mode
+    ///
+    /// \return Server response to the request
+    ///
+    /// \see download
+    ///
+    ////////////////////////////////////////////////////////////
+    Response upload(const std::string& localFile, const std::string& remotePath, TransferMode mode = Binary);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send a command to the FTP server
+    ///
+    /// While the most often used commands are provided as member
+    /// functions in the sf::Ftp class, this method can be used
+    /// to send any FTP command to the server. If the command
+    /// requires one or more parameters, they can be specified
+    /// in \a parameter. If the server returns information, you
+    /// can extract it from the response using Response::getMessage().
+    ///
+    /// \param command   Command to send
+    /// \param parameter Command parameter
+    ///
+    /// \return Server response to the request
+    ///
+    ////////////////////////////////////////////////////////////
+    Response sendCommand(const std::string& command, const std::string& parameter = "");
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Receive a response from the server
+    ///
+    /// This function must be called after each call to
+    /// sendCommand that expects a response.
+    ///
+    /// \return Server response to the request
+    ///
+    ////////////////////////////////////////////////////////////
+    Response getResponse();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Utility class for exchanging datas with the server
+    ///        on the data channel
+    ///
+    ////////////////////////////////////////////////////////////
+    class DataChannel;
+
+    friend class DataChannel;
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    TcpSocket m_commandSocket; ///< Socket holding the control connection with the server
+};
+
+} // namespace sf
+
+
+#endif // SFML_FTP_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Ftp
+/// \ingroup network
+///
+/// sf::Ftp is a very simple FTP client that allows you
+/// to communicate with a FTP server. The FTP protocol allows
+/// you to manipulate a remote file system (list files,
+/// upload, download, create, remove, ...).
+///
+/// Using the FTP client consists of 4 parts:
+/// \li Connecting to the FTP server
+/// \li Logging in (either as a registered user or anonymously)
+/// \li Sending commands to the server
+/// \li Disconnecting (this part can be done implicitly by the destructor)
+///
+/// Every command returns a FTP response, which contains the
+/// status code as well as a message from the server. Some
+/// commands such as getWorkingDirectory() and getDirectoryListing()
+/// return additional data, and use a class derived from
+/// sf::Ftp::Response to provide this data. The most often used
+/// commands are directly provided as member functions, but it is
+/// also possible to use specific commands with the sendCommand() method.
+///
+/// All commands, especially upload and download, may take some
+/// time to complete. This is important to know if you don't want
+/// to block your application while the server is completing
+/// the task.
+///
+/// Usage example:
+/// \code
+/// // Create a new FTP client
+/// sf::Ftp ftp;
+///
+/// // Connect to the server
+/// sf::Ftp::Response response = ftp.connect("ftp://ftp.myserver.com");
+/// if (response.isOk())
+///     std::cout << "Connected" << std::endl;
+///
+/// // Log in
+/// response = ftp.login("laurent", "dF6Zm89D");
+/// if (response.isOk())
+///     std::cout << "Logged in" << std::endl;
+///
+/// // Print the working directory
+/// sf::Ftp::DirectoryResponse directory = ftp.getWorkingDirectory();
+/// if (directory.isOk())
+///     std::cout << "Working directory: " << directory.getDirectory() << std::endl;
+///
+/// // Create a new directory
+/// response = ftp.createDirectory("files");
+/// if (response.isOk())
+///     std::cout << "Created new directory" << std::endl;
+///
+/// // Upload a file to this new directory
+/// response = ftp.upload("local-path/file.txt", "files", sf::Ftp::Ascii);
+/// if (response.isOk())
+///     std::cout << "File uploaded" << std::endl;
+///
+/// // Send specific commands (here: FEAT to list supported FTP features)
+/// response = ftp.sendCommand("FEAT");
+/// if (response.isOk())
+///     std::cout << "Feature list:\n" << response.getMessage() << std::endl;
+///
+/// // Disconnect from the server (optional)
+/// ftp.disconnect();
+/// \endcode
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/Http.hpp b/dependencies64/sfml/include/SFML/Network/Http.hpp
new file mode 100644 (file)
index 0000000..fec109c
--- /dev/null
@@ -0,0 +1,482 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_HTTP_HPP
+#define SFML_HTTP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/Network/IpAddress.hpp>
+#include <SFML/Network/TcpSocket.hpp>
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/System/Time.hpp>
+#include <map>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief A HTTP client
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API Http : NonCopyable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Define a HTTP request
+    ///
+    ////////////////////////////////////////////////////////////
+    class SFML_NETWORK_API Request
+    {
+    public:
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Enumerate the available HTTP methods for a request
+        ///
+        ////////////////////////////////////////////////////////////
+        enum Method
+        {
+            Get,   ///< Request in get mode, standard method to retrieve a page
+            Post,  ///< Request in post mode, usually to send data to a page
+            Head,  ///< Request a page's header only
+            Put,   ///< Request in put mode, useful for a REST API
+            Delete ///< Request in delete mode, useful for a REST API
+        };
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Default constructor
+        ///
+        /// This constructor creates a GET request, with the root
+        /// URI ("/") and an empty body.
+        ///
+        /// \param uri    Target URI
+        /// \param method Method to use for the request
+        /// \param body   Content of the request's body
+        ///
+        ////////////////////////////////////////////////////////////
+        Request(const std::string& uri = "/", Method method = Get, const std::string& body = "");
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Set the value of a field
+        ///
+        /// The field is created if it doesn't exist. The name of
+        /// the field is case-insensitive.
+        /// By default, a request doesn't contain any field (but the
+        /// mandatory fields are added later by the HTTP client when
+        /// sending the request).
+        ///
+        /// \param field Name of the field to set
+        /// \param value Value of the field
+        ///
+        ////////////////////////////////////////////////////////////
+        void setField(const std::string& field, const std::string& value);
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Set the request method
+        ///
+        /// See the Method enumeration for a complete list of all
+        /// the availale methods.
+        /// The method is Http::Request::Get by default.
+        ///
+        /// \param method Method to use for the request
+        ///
+        ////////////////////////////////////////////////////////////
+        void setMethod(Method method);
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Set the requested URI
+        ///
+        /// The URI is the resource (usually a web page or a file)
+        /// that you want to get or post.
+        /// The URI is "/" (the root page) by default.
+        ///
+        /// \param uri URI to request, relative to the host
+        ///
+        ////////////////////////////////////////////////////////////
+        void setUri(const std::string& uri);
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Set the HTTP version for the request
+        ///
+        /// The HTTP version is 1.0 by default.
+        ///
+        /// \param major Major HTTP version number
+        /// \param minor Minor HTTP version number
+        ///
+        ////////////////////////////////////////////////////////////
+        void setHttpVersion(unsigned int major, unsigned int minor);
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Set the body of the request
+        ///
+        /// The body of a request is optional and only makes sense
+        /// for POST requests. It is ignored for all other methods.
+        /// The body is empty by default.
+        ///
+        /// \param body Content of the body
+        ///
+        ////////////////////////////////////////////////////////////
+        void setBody(const std::string& body);
+
+    private:
+
+        friend class Http;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Prepare the final request to send to the server
+        ///
+        /// This is used internally by Http before sending the
+        /// request to the web server.
+        ///
+        /// \return String containing the request, ready to be sent
+        ///
+        ////////////////////////////////////////////////////////////
+        std::string prepare() const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Check if the request defines a field
+        ///
+        /// This function uses case-insensitive comparisons.
+        ///
+        /// \param field Name of the field to test
+        ///
+        /// \return True if the field exists, false otherwise
+        ///
+        ////////////////////////////////////////////////////////////
+        bool hasField(const std::string& field) const;
+
+        ////////////////////////////////////////////////////////////
+        // Types
+        ////////////////////////////////////////////////////////////
+        typedef std::map<std::string, std::string> FieldTable;
+
+        ////////////////////////////////////////////////////////////
+        // Member data
+        ////////////////////////////////////////////////////////////
+        FieldTable   m_fields;       ///< Fields of the header associated to their value
+        Method       m_method;       ///< Method to use for the request
+        std::string  m_uri;          ///< Target URI of the request
+        unsigned int m_majorVersion; ///< Major HTTP version
+        unsigned int m_minorVersion; ///< Minor HTTP version
+        std::string  m_body;         ///< Body of the request
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Define a HTTP response
+    ///
+    ////////////////////////////////////////////////////////////
+    class SFML_NETWORK_API Response
+    {
+    public:
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Enumerate all the valid status codes for a response
+        ///
+        ////////////////////////////////////////////////////////////
+        enum Status
+        {
+            // 2xx: success
+            Ok             = 200, ///< Most common code returned when operation was successful
+            Created        = 201, ///< The resource has successfully been created
+            Accepted       = 202, ///< The request has been accepted, but will be processed later by the server
+            NoContent      = 204, ///< The server didn't send any data in return
+            ResetContent   = 205, ///< The server informs the client that it should clear the view (form) that caused the request to be sent
+            PartialContent = 206, ///< The server has sent a part of the resource, as a response to a partial GET request
+
+            // 3xx: redirection
+            MultipleChoices  = 300, ///< The requested page can be accessed from several locations
+            MovedPermanently = 301, ///< The requested page has permanently moved to a new location
+            MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
+            NotModified      = 304, ///< For conditional requests, means the requested page hasn't changed and doesn't need to be refreshed
+
+            // 4xx: client error
+            BadRequest          = 400, ///< The server couldn't understand the request (syntax error)
+            Unauthorized        = 401, ///< The requested page needs an authentication to be accessed
+            Forbidden           = 403, ///< The requested page cannot be accessed at all, even with authentication
+            NotFound            = 404, ///< The requested page doesn't exist
+            RangeNotSatisfiable = 407, ///< The server can't satisfy the partial GET request (with a "Range" header field)
+
+            // 5xx: server error
+            InternalServerError = 500, ///< The server encountered an unexpected error
+            NotImplemented      = 501, ///< The server doesn't implement a requested feature
+            BadGateway          = 502, ///< The gateway server has received an error from the source server
+            ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
+            GatewayTimeout      = 504, ///< The gateway server couldn't receive a response from the source server
+            VersionNotSupported = 505, ///< The server doesn't support the requested HTTP version
+
+            // 10xx: SFML custom codes
+            InvalidResponse  = 1000, ///< Response is not a valid HTTP one
+            ConnectionFailed = 1001  ///< Connection with server failed
+        };
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Default constructor
+        ///
+        /// Constructs an empty response.
+        ///
+        ////////////////////////////////////////////////////////////
+        Response();
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the value of a field
+        ///
+        /// If the field \a field is not found in the response header,
+        /// the empty string is returned. This function uses
+        /// case-insensitive comparisons.
+        ///
+        /// \param field Name of the field to get
+        ///
+        /// \return Value of the field, or empty string if not found
+        ///
+        ////////////////////////////////////////////////////////////
+        const std::string& getField(const std::string& field) const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the response status code
+        ///
+        /// The status code should be the first thing to be checked
+        /// after receiving a response, it defines whether it is a
+        /// success, a failure or anything else (see the Status
+        /// enumeration).
+        ///
+        /// \return Status code of the response
+        ///
+        ////////////////////////////////////////////////////////////
+        Status getStatus() const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the major HTTP version number of the response
+        ///
+        /// \return Major HTTP version number
+        ///
+        /// \see getMinorHttpVersion
+        ///
+        ////////////////////////////////////////////////////////////
+        unsigned int getMajorHttpVersion() const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the minor HTTP version number of the response
+        ///
+        /// \return Minor HTTP version number
+        ///
+        /// \see getMajorHttpVersion
+        ///
+        ////////////////////////////////////////////////////////////
+        unsigned int getMinorHttpVersion() const;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Get the body of the response
+        ///
+        /// The body of a response may contain:
+        /// \li the requested page (for GET requests)
+        /// \li a response from the server (for POST requests)
+        /// \li nothing (for HEAD requests)
+        /// \li an error message (in case of an error)
+        ///
+        /// \return The response body
+        ///
+        ////////////////////////////////////////////////////////////
+        const std::string& getBody() const;
+
+    private:
+
+        friend class Http;
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Construct the header from a response string
+        ///
+        /// This function is used by Http to build the response
+        /// of a request.
+        ///
+        /// \param data Content of the response to parse
+        ///
+        ////////////////////////////////////////////////////////////
+        void parse(const std::string& data);
+
+
+        ////////////////////////////////////////////////////////////
+        /// \brief Read values passed in the answer header
+        ///
+        /// This function is used by Http to extract values passed
+        /// in the response.
+        ///
+        /// \param in String stream containing the header values
+        ///
+        ////////////////////////////////////////////////////////////
+        void parseFields(std::istream &in);
+
+        ////////////////////////////////////////////////////////////
+        // Types
+        ////////////////////////////////////////////////////////////
+        typedef std::map<std::string, std::string> FieldTable;
+
+        ////////////////////////////////////////////////////////////
+        // Member data
+        ////////////////////////////////////////////////////////////
+        FieldTable   m_fields;       ///< Fields of the header
+        Status       m_status;       ///< Status code
+        unsigned int m_majorVersion; ///< Major HTTP version
+        unsigned int m_minorVersion; ///< Minor HTTP version
+        std::string  m_body;         ///< Body of the response
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    Http();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the HTTP client with the target host
+    ///
+    /// This is equivalent to calling setHost(host, port).
+    /// The port has a default value of 0, which means that the
+    /// HTTP client will use the right port according to the
+    /// protocol used (80 for HTTP). You should leave it like
+    /// this unless you really need a port other than the
+    /// standard one, or use an unknown protocol.
+    ///
+    /// \param host Web server to connect to
+    /// \param port Port to use for connection
+    ///
+    ////////////////////////////////////////////////////////////
+    Http(const std::string& host, unsigned short port = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the target host
+    ///
+    /// This function just stores the host address and port, it
+    /// doesn't actually connect to it until you send a request.
+    /// The port has a default value of 0, which means that the
+    /// HTTP client will use the right port according to the
+    /// protocol used (80 for HTTP). You should leave it like
+    /// this unless you really need a port other than the
+    /// standard one, or use an unknown protocol.
+    ///
+    /// \param host Web server to connect to
+    /// \param port Port to use for connection
+    ///
+    ////////////////////////////////////////////////////////////
+    void setHost(const std::string& host, unsigned short port = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send a HTTP request and return the server's response.
+    ///
+    /// You must have a valid host before sending a request (see setHost).
+    /// Any missing mandatory header field in the request will be added
+    /// with an appropriate value.
+    /// Warning: this function waits for the server's response and may
+    /// not return instantly; use a thread if you don't want to block your
+    /// application, or use a timeout to limit the time to wait. A value
+    /// of Time::Zero means that the client will use the system default timeout
+    /// (which is usually pretty long).
+    ///
+    /// \param request Request to send
+    /// \param timeout Maximum time to wait
+    ///
+    /// \return Server's response
+    ///
+    ////////////////////////////////////////////////////////////
+    Response sendRequest(const Request& request, Time timeout = Time::Zero);
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    TcpSocket      m_connection; ///< Connection to the host
+    IpAddress      m_host;       ///< Web host address
+    std::string    m_hostName;   ///< Web host name
+    unsigned short m_port;       ///< Port used for connection with host
+};
+
+} // namespace sf
+
+
+#endif // SFML_HTTP_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Http
+/// \ingroup network
+///
+/// sf::Http is a very simple HTTP client that allows you
+/// to communicate with a web server. You can retrieve
+/// web pages, send data to an interactive resource,
+/// download a remote file, etc. The HTTPS protocol is
+/// not supported.
+///
+/// The HTTP client is split into 3 classes:
+/// \li sf::Http::Request
+/// \li sf::Http::Response
+/// \li sf::Http
+///
+/// sf::Http::Request builds the request that will be
+/// sent to the server. A request is made of:
+/// \li a method (what you want to do)
+/// \li a target URI (usually the name of the web page or file)
+/// \li one or more header fields (options that you can pass to the server)
+/// \li an optional body (for POST requests)
+///
+/// sf::Http::Response parse the response from the web server
+/// and provides getters to read them. The response contains:
+/// \li a status code
+/// \li header fields (that may be answers to the ones that you requested)
+/// \li a body, which contains the contents of the requested resource
+///
+/// sf::Http provides a simple function, SendRequest, to send a
+/// sf::Http::Request and return the corresponding sf::Http::Response
+/// from the server.
+///
+/// Usage example:
+/// \code
+/// // Create a new HTTP client
+/// sf::Http http;
+///
+/// // We'll work on http://www.sfml-dev.org
+/// http.setHost("http://www.sfml-dev.org");
+///
+/// // Prepare a request to get the 'features.php' page
+/// sf::Http::Request request("features.php");
+///
+/// // Send the request
+/// sf::Http::Response response = http.sendRequest(request);
+///
+/// // Check the status code and display the result
+/// sf::Http::Response::Status status = response.getStatus();
+/// if (status == sf::Http::Response::Ok)
+/// {
+///     std::cout << response.getBody() << std::endl;
+/// }
+/// else
+/// {
+///     std::cout << "Error " << status << std::endl;
+/// }
+/// \endcode
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/IpAddress.hpp b/dependencies64/sfml/include/SFML/Network/IpAddress.hpp
new file mode 100644 (file)
index 0000000..77b0cf5
--- /dev/null
@@ -0,0 +1,316 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_IPADDRESS_HPP
+#define SFML_IPADDRESS_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/System/Time.hpp>
+#include <istream>
+#include <ostream>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Encapsulate an IPv4 network address
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API IpAddress
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor creates an empty (invalid) address
+    ///
+    ////////////////////////////////////////////////////////////
+    IpAddress();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the address from a string
+    ///
+    /// Here \a address can be either a decimal address
+    /// (ex: "192.168.1.56") or a network name (ex: "localhost").
+    ///
+    /// \param address IP address or network name
+    ///
+    ////////////////////////////////////////////////////////////
+    IpAddress(const std::string& address);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the address from a string
+    ///
+    /// Here \a address can be either a decimal address
+    /// (ex: "192.168.1.56") or a network name (ex: "localhost").
+    /// This is equivalent to the constructor taking a std::string
+    /// parameter, it is defined for convenience so that the
+    /// implicit conversions from literal strings to IpAddress work.
+    ///
+    /// \param address IP address or network name
+    ///
+    ////////////////////////////////////////////////////////////
+    IpAddress(const char* address);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the address from 4 bytes
+    ///
+    /// Calling IpAddress(a, b, c, d) is equivalent to calling
+    /// IpAddress("a.b.c.d"), but safer as it doesn't have to
+    /// parse a string to get the address components.
+    ///
+    /// \param byte0 First byte of the address
+    /// \param byte1 Second byte of the address
+    /// \param byte2 Third byte of the address
+    /// \param byte3 Fourth byte of the address
+    ///
+    ////////////////////////////////////////////////////////////
+    IpAddress(Uint8 byte0, Uint8 byte1, Uint8 byte2, Uint8 byte3);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the address from a 32-bits integer
+    ///
+    /// This constructor uses the internal representation of
+    /// the address directly. It should be used for optimization
+    /// purposes, and only if you got that representation from
+    /// IpAddress::ToInteger().
+    ///
+    /// \param address 4 bytes of the address packed into a 32-bits integer
+    ///
+    /// \see toInteger
+    ///
+    ////////////////////////////////////////////////////////////
+    explicit IpAddress(Uint32 address);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a string representation of the address
+    ///
+    /// The returned string is the decimal representation of the
+    /// IP address (like "192.168.1.56"), even if it was constructed
+    /// from a host name.
+    ///
+    /// \return String representation of the address
+    ///
+    /// \see toInteger
+    ///
+    ////////////////////////////////////////////////////////////
+    std::string toString() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get an integer representation of the address
+    ///
+    /// The returned number is the internal representation of the
+    /// address, and should be used for optimization purposes only
+    /// (like sending the address through a socket).
+    /// The integer produced by this function can then be converted
+    /// back to a sf::IpAddress with the proper constructor.
+    ///
+    /// \return 32-bits unsigned integer representation of the address
+    ///
+    /// \see toString
+    ///
+    ////////////////////////////////////////////////////////////
+    Uint32 toInteger() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the computer's local address
+    ///
+    /// The local address is the address of the computer from the
+    /// LAN point of view, i.e. something like 192.168.1.56. It is
+    /// meaningful only for communications over the local network.
+    /// Unlike getPublicAddress, this function is fast and may be
+    /// used safely anywhere.
+    ///
+    /// \return Local IP address of the computer
+    ///
+    /// \see getPublicAddress
+    ///
+    ////////////////////////////////////////////////////////////
+    static IpAddress getLocalAddress();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the computer's public address
+    ///
+    /// The public address is the address of the computer from the
+    /// internet point of view, i.e. something like 89.54.1.169.
+    /// It is necessary for communications over the world wide web.
+    /// The only way to get a public address is to ask it to a
+    /// distant website; as a consequence, this function depends on
+    /// both your network connection and the server, and may be
+    /// very slow. You should use it as few as possible. Because
+    /// this function depends on the network connection and on a distant
+    /// server, you may use a time limit if you don't want your program
+    /// to be possibly stuck waiting in case there is a problem; this
+    /// limit is deactivated by default.
+    ///
+    /// \param timeout Maximum time to wait
+    ///
+    /// \return Public IP address of the computer
+    ///
+    /// \see getLocalAddress
+    ///
+    ////////////////////////////////////////////////////////////
+    static IpAddress getPublicAddress(Time timeout = Time::Zero);
+
+    ////////////////////////////////////////////////////////////
+    // Static member data
+    ////////////////////////////////////////////////////////////
+    static const IpAddress None;      ///< Value representing an empty/invalid address
+    static const IpAddress LocalHost; ///< The "localhost" address (for connecting a computer to itself locally)
+    static const IpAddress Broadcast; ///< The "broadcast" address (for sending UDP messages to everyone on a local network)
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Uint32 m_address; ///< Address stored as an unsigned 32 bits integer
+};
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of == operator to compare two IP addresses
+///
+/// \param left  Left operand (a IP address)
+/// \param right Right operand (a IP address)
+///
+/// \return True if both addresses are equal
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API bool operator ==(const IpAddress& left, const IpAddress& right);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of != operator to compare two IP addresses
+///
+/// \param left  Left operand (a IP address)
+/// \param right Right operand (a IP address)
+///
+/// \return True if both addresses are different
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API bool operator !=(const IpAddress& left, const IpAddress& right);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of < operator to compare two IP addresses
+///
+/// \param left  Left operand (a IP address)
+/// \param right Right operand (a IP address)
+///
+/// \return True if \a left is lesser than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API bool operator <(const IpAddress& left, const IpAddress& right);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of > operator to compare two IP addresses
+///
+/// \param left  Left operand (a IP address)
+/// \param right Right operand (a IP address)
+///
+/// \return True if \a left is greater than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API bool operator >(const IpAddress& left, const IpAddress& right);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of <= operator to compare two IP addresses
+///
+/// \param left  Left operand (a IP address)
+/// \param right Right operand (a IP address)
+///
+/// \return True if \a left is lesser or equal than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API bool operator <=(const IpAddress& left, const IpAddress& right);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of >= operator to compare two IP addresses
+///
+/// \param left  Left operand (a IP address)
+/// \param right Right operand (a IP address)
+///
+/// \return True if \a left is greater or equal than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API bool operator >=(const IpAddress& left, const IpAddress& right);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of >> operator to extract an IP address from an input stream
+///
+/// \param stream  Input stream
+/// \param address IP address to extract
+///
+/// \return Reference to the input stream
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API std::istream& operator >>(std::istream& stream, IpAddress& address);
+
+////////////////////////////////////////////////////////////
+/// \brief Overload of << operator to print an IP address to an output stream
+///
+/// \param stream  Output stream
+/// \param address IP address to print
+///
+/// \return Reference to the output stream
+///
+////////////////////////////////////////////////////////////
+SFML_NETWORK_API std::ostream& operator <<(std::ostream& stream, const IpAddress& address);
+
+} // namespace sf
+
+
+#endif // SFML_IPADDRESS_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::IpAddress
+/// \ingroup network
+///
+/// sf::IpAddress is a utility class for manipulating network
+/// addresses. It provides a set a implicit constructors and
+/// conversion functions to easily build or transform an IP
+/// address from/to various representations.
+///
+/// Usage example:
+/// \code
+/// sf::IpAddress a0;                                     // an invalid address
+/// sf::IpAddress a1 = sf::IpAddress::None;               // an invalid address (same as a0)
+/// sf::IpAddress a2("127.0.0.1");                        // the local host address
+/// sf::IpAddress a3 = sf::IpAddress::Broadcast;          // the broadcast address
+/// sf::IpAddress a4(192, 168, 1, 56);                    // a local address
+/// sf::IpAddress a5("my_computer");                      // a local address created from a network name
+/// sf::IpAddress a6("89.54.1.169");                      // a distant address
+/// sf::IpAddress a7("www.google.com");                   // a distant address created from a network name
+/// sf::IpAddress a8 = sf::IpAddress::getLocalAddress();  // my address on the local network
+/// sf::IpAddress a9 = sf::IpAddress::getPublicAddress(); // my address on the internet
+/// \endcode
+///
+/// Note that sf::IpAddress currently doesn't support IPv6
+/// nor other types of network addresses.
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/Packet.hpp b/dependencies64/sfml/include/SFML/Network/Packet.hpp
new file mode 100644 (file)
index 0000000..a400aae
--- /dev/null
@@ -0,0 +1,411 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_PACKET_HPP
+#define SFML_PACKET_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+class String;
+class TcpSocket;
+class UdpSocket;
+
+////////////////////////////////////////////////////////////
+/// \brief Utility class to build blocks of data to transfer
+///        over the network
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API Packet
+{
+    // A bool-like type that cannot be converted to integer or pointer types
+    typedef bool (Packet::*BoolType)(std::size_t);
+
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Creates an empty packet.
+    ///
+    ////////////////////////////////////////////////////////////
+    Packet();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Virtual destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~Packet();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Append data to the end of the packet
+    ///
+    /// \param data        Pointer to the sequence of bytes to append
+    /// \param sizeInBytes Number of bytes to append
+    ///
+    /// \see clear
+    ///
+    ////////////////////////////////////////////////////////////
+    void append(const void* data, std::size_t sizeInBytes);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Clear the packet
+    ///
+    /// After calling Clear, the packet is empty.
+    ///
+    /// \see append
+    ///
+    ////////////////////////////////////////////////////////////
+    void clear();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a pointer to the data contained in the packet
+    ///
+    /// Warning: the returned pointer may become invalid after
+    /// you append data to the packet, therefore it should never
+    /// be stored.
+    /// The return pointer is NULL if the packet is empty.
+    ///
+    /// \return Pointer to the data
+    ///
+    /// \see getDataSize
+    ///
+    ////////////////////////////////////////////////////////////
+    const void* getData() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the size of the data contained in the packet
+    ///
+    /// This function returns the number of bytes pointed to by
+    /// what getData returns.
+    ///
+    /// \return Data size, in bytes
+    ///
+    /// \see getData
+    ///
+    ////////////////////////////////////////////////////////////
+    std::size_t getDataSize() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell if the reading position has reached the
+    ///        end of the packet
+    ///
+    /// This function is useful to know if there is some data
+    /// left to be read, without actually reading it.
+    ///
+    /// \return True if all data was read, false otherwise
+    ///
+    /// \see operator bool
+    ///
+    ////////////////////////////////////////////////////////////
+    bool endOfPacket() const;
+
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Test the validity of the packet, for reading
+    ///
+    /// This operator allows to test the packet as a boolean
+    /// variable, to check if a reading operation was successful.
+    ///
+    /// A packet will be in an invalid state if it has no more
+    /// data to read.
+    ///
+    /// This behavior is the same as standard C++ streams.
+    ///
+    /// Usage example:
+    /// \code
+    /// float x;
+    /// packet >> x;
+    /// if (packet)
+    /// {
+    ///    // ok, x was extracted successfully
+    /// }
+    ///
+    /// // -- or --
+    ///
+    /// float x;
+    /// if (packet >> x)
+    /// {
+    ///    // ok, x was extracted successfully
+    /// }
+    /// \endcode
+    ///
+    /// Don't focus on the return type, it's equivalent to bool but
+    /// it disallows unwanted implicit conversions to integer or
+    /// pointer types.
+    ///
+    /// \return True if last data extraction from packet was successful
+    ///
+    /// \see endOfPacket
+    ///
+    ////////////////////////////////////////////////////////////
+    operator BoolType() const;
+
+    ////////////////////////////////////////////////////////////
+    /// Overloads of operator >> to read data from the packet
+    ///
+    ////////////////////////////////////////////////////////////
+    Packet& operator >>(bool&         data);
+    Packet& operator >>(Int8&         data);
+    Packet& operator >>(Uint8&        data);
+    Packet& operator >>(Int16&        data);
+    Packet& operator >>(Uint16&       data);
+    Packet& operator >>(Int32&        data);
+    Packet& operator >>(Uint32&       data);
+    Packet& operator >>(Int64&        data);
+    Packet& operator >>(Uint64&       data);
+    Packet& operator >>(float&        data);
+    Packet& operator >>(double&       data);
+    Packet& operator >>(char*         data);
+    Packet& operator >>(std::string&  data);
+    Packet& operator >>(wchar_t*      data);
+    Packet& operator >>(std::wstring& data);
+    Packet& operator >>(String&       data);
+
+    ////////////////////////////////////////////////////////////
+    /// Overloads of operator << to write data into the packet
+    ///
+    ////////////////////////////////////////////////////////////
+    Packet& operator <<(bool                data);
+    Packet& operator <<(Int8                data);
+    Packet& operator <<(Uint8               data);
+    Packet& operator <<(Int16               data);
+    Packet& operator <<(Uint16              data);
+    Packet& operator <<(Int32               data);
+    Packet& operator <<(Uint32              data);
+    Packet& operator <<(Int64               data);
+    Packet& operator <<(Uint64              data);
+    Packet& operator <<(float               data);
+    Packet& operator <<(double              data);
+    Packet& operator <<(const char*         data);
+    Packet& operator <<(const std::string&  data);
+    Packet& operator <<(const wchar_t*      data);
+    Packet& operator <<(const std::wstring& data);
+    Packet& operator <<(const String&       data);
+
+protected:
+
+    friend class TcpSocket;
+    friend class UdpSocket;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Called before the packet is sent over the network
+    ///
+    /// This function can be defined by derived classes to
+    /// transform the data before it is sent; this can be
+    /// used for compression, encryption, etc.
+    /// The function must return a pointer to the modified data,
+    /// as well as the number of bytes pointed.
+    /// The default implementation provides the packet's data
+    /// without transforming it.
+    ///
+    /// \param size Variable to fill with the size of data to send
+    ///
+    /// \return Pointer to the array of bytes to send
+    ///
+    /// \see onReceive
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual const void* onSend(std::size_t& size);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Called after the packet is received over the network
+    ///
+    /// This function can be defined by derived classes to
+    /// transform the data after it is received; this can be
+    /// used for decompression, decryption, etc.
+    /// The function receives a pointer to the received data,
+    /// and must fill the packet with the transformed bytes.
+    /// The default implementation fills the packet directly
+    /// without transforming the data.
+    ///
+    /// \param data Pointer to the received bytes
+    /// \param size Number of bytes
+    ///
+    /// \see onSend
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual void onReceive(const void* data, std::size_t size);
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    /// Disallow comparisons between packets
+    ///
+    ////////////////////////////////////////////////////////////
+    bool operator ==(const Packet& right) const;
+    bool operator !=(const Packet& right) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if the packet can extract a given number of bytes
+    ///
+    /// This function updates accordingly the state of the packet.
+    ///
+    /// \param size Size to check
+    ///
+    /// \return True if \a size bytes can be read from the packet
+    ///
+    ////////////////////////////////////////////////////////////
+    bool checkSize(std::size_t size);
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    std::vector<char> m_data;    ///< Data stored in the packet
+    std::size_t       m_readPos; ///< Current reading position in the packet
+    bool              m_isValid; ///< Reading state of the packet
+};
+
+} // namespace sf
+
+
+#endif // SFML_PACKET_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Packet
+/// \ingroup network
+///
+/// Packets provide a safe and easy way to serialize data,
+/// in order to send it over the network using sockets
+/// (sf::TcpSocket, sf::UdpSocket).
+///
+/// Packets solve 2 fundamental problems that arise when
+/// transferring data over the network:
+/// \li data is interpreted correctly according to the endianness
+/// \li the bounds of the packet are preserved (one send == one receive)
+///
+/// The sf::Packet class provides both input and output modes.
+/// It is designed to follow the behavior of standard C++ streams,
+/// using operators >> and << to extract and insert data.
+///
+/// It is recommended to use only fixed-size types (like sf::Int32, etc.),
+/// to avoid possible differences between the sender and the receiver.
+/// Indeed, the native C++ types may have different sizes on two platforms
+/// and your data may be corrupted if that happens.
+///
+/// Usage example:
+/// \code
+/// sf::Uint32 x = 24;
+/// std::string s = "hello";
+/// double d = 5.89;
+///
+/// // Group the variables to send into a packet
+/// sf::Packet packet;
+/// packet << x << s << d;
+///
+/// // Send it over the network (socket is a valid sf::TcpSocket)
+/// socket.send(packet);
+///
+/// -----------------------------------------------------------------
+///
+/// // Receive the packet at the other end
+/// sf::Packet packet;
+/// socket.receive(packet);
+///
+/// // Extract the variables contained in the packet
+/// sf::Uint32 x;
+/// std::string s;
+/// double d;
+/// if (packet >> x >> s >> d)
+/// {
+///     // Data extracted successfully...
+/// }
+/// \endcode
+///
+/// Packets have built-in operator >> and << overloads for
+/// standard types:
+/// \li bool
+/// \li fixed-size integer types (sf::Int8/16/32, sf::Uint8/16/32)
+/// \li floating point numbers (float, double)
+/// \li string types (char*, wchar_t*, std::string, std::wstring, sf::String)
+///
+/// Like standard streams, it is also possible to define your own
+/// overloads of operators >> and << in order to handle your
+/// custom types.
+///
+/// \code
+/// struct MyStruct
+/// {
+///     float       number;
+///     sf::Int8    integer;
+///     std::string str;
+/// };
+///
+/// sf::Packet& operator <<(sf::Packet& packet, const MyStruct& m)
+/// {
+///     return packet << m.number << m.integer << m.str;
+/// }
+///
+/// sf::Packet& operator >>(sf::Packet& packet, MyStruct& m)
+/// {
+///     return packet >> m.number >> m.integer >> m.str;
+/// }
+/// \endcode
+///
+/// Packets also provide an extra feature that allows to apply
+/// custom transformations to the data before it is sent,
+/// and after it is received. This is typically used to
+/// handle automatic compression or encryption of the data.
+/// This is achieved by inheriting from sf::Packet, and overriding
+/// the onSend and onReceive functions.
+///
+/// Here is an example:
+/// \code
+/// class ZipPacket : public sf::Packet
+/// {
+///     virtual const void* onSend(std::size_t& size)
+///     {
+///         const void* srcData = getData();
+///         std::size_t srcSize = getDataSize();
+///
+///         return MySuperZipFunction(srcData, srcSize, &size);
+///     }
+///
+///     virtual void onReceive(const void* data, std::size_t size)
+///     {
+///         std::size_t dstSize;
+///         const void* dstData = MySuperUnzipFunction(data, size, &dstSize);
+///
+///         append(dstData, dstSize);
+///     }
+/// };
+///
+/// // Use like regular packets:
+/// ZipPacket packet;
+/// packet << x << s << d;
+/// ...
+/// \endcode
+///
+/// \see sf::TcpSocket, sf::UdpSocket
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/Socket.hpp b/dependencies64/sfml/include/SFML/Network/Socket.hpp
new file mode 100644 (file)
index 0000000..8b66453
--- /dev/null
@@ -0,0 +1,218 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKET_HPP
+#define SFML_SOCKET_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/Network/SocketHandle.hpp>
+#include <SFML/System/NonCopyable.hpp>
+#include <vector>
+
+
+namespace sf
+{
+class SocketSelector;
+
+////////////////////////////////////////////////////////////
+/// \brief Base class for all the socket types
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API Socket : NonCopyable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Status codes that may be returned by socket functions
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Status
+    {
+        Done,         ///< The socket has sent / received the data
+        NotReady,     ///< The socket is not ready to send / receive data yet
+        Disconnected, ///< The TCP socket has been disconnected
+        Error         ///< An unexpected error happened
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Some special values used by sockets
+    ///
+    ////////////////////////////////////////////////////////////
+    enum
+    {
+        AnyPort = 0 ///< Special value that tells the system to pick any available port
+    };
+
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~Socket();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the blocking state of the socket
+    ///
+    /// In blocking mode, calls will not return until they have
+    /// completed their task. For example, a call to Receive in
+    /// blocking mode won't return until some data was actually
+    /// received.
+    /// In non-blocking mode, calls will always return immediately,
+    /// using the return code to signal whether there was data
+    /// available or not.
+    /// By default, all sockets are blocking.
+    ///
+    /// \param blocking True to set the socket as blocking, false for non-blocking
+    ///
+    /// \see isBlocking
+    ///
+    ////////////////////////////////////////////////////////////
+    void setBlocking(bool blocking);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Tell whether the socket is in blocking or non-blocking mode
+    ///
+    /// \return True if the socket is blocking, false otherwise
+    ///
+    /// \see setBlocking
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isBlocking() const;
+
+protected:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Types of protocols that the socket can use
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Type
+    {
+        Tcp, ///< TCP protocol
+        Udp  ///< UDP protocol
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor can only be accessed by derived classes.
+    ///
+    /// \param type Type of the socket (TCP or UDP)
+    ///
+    ////////////////////////////////////////////////////////////
+    Socket(Type type);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the internal handle of the socket
+    ///
+    /// The returned handle may be invalid if the socket
+    /// was not created yet (or already destroyed).
+    /// This function can only be accessed by derived classes.
+    ///
+    /// \return The internal (OS-specific) handle of the socket
+    ///
+    ////////////////////////////////////////////////////////////
+    SocketHandle getHandle() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create the internal representation of the socket
+    ///
+    /// This function can only be accessed by derived classes.
+    ///
+    ////////////////////////////////////////////////////////////
+    void create();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create the internal representation of the socket
+    ///        from a socket handle
+    ///
+    /// This function can only be accessed by derived classes.
+    ///
+    /// \param handle OS-specific handle of the socket to wrap
+    ///
+    ////////////////////////////////////////////////////////////
+    void create(SocketHandle handle);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Close the socket gracefully
+    ///
+    /// This function can only be accessed by derived classes.
+    ///
+    ////////////////////////////////////////////////////////////
+    void close();
+
+private:
+
+    friend class SocketSelector;
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Type         m_type;       ///< Type of the socket (TCP or UDP)
+    SocketHandle m_socket;     ///< Socket descriptor
+    bool         m_isBlocking; ///< Current blocking mode of the socket
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKET_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Socket
+/// \ingroup network
+///
+/// This class mainly defines internal stuff to be used by
+/// derived classes.
+///
+/// The only public features that it defines, and which
+/// is therefore common to all the socket classes, is the
+/// blocking state. All sockets can be set as blocking or
+/// non-blocking.
+///
+/// In blocking mode, socket functions will hang until
+/// the operation completes, which means that the entire
+/// program (well, in fact the current thread if you use
+/// multiple ones) will be stuck waiting for your socket
+/// operation to complete.
+///
+/// In non-blocking mode, all the socket functions will
+/// return immediately. If the socket is not ready to complete
+/// the requested operation, the function simply returns
+/// the proper status code (Socket::NotReady).
+///
+/// The default mode, which is blocking, is the one that is
+/// generally used, in combination with threads or selectors.
+/// The non-blocking mode is rather used in real-time
+/// applications that run an endless loop that can poll
+/// the socket often enough, and cannot afford blocking
+/// this loop.
+///
+/// \see sf::TcpListener, sf::TcpSocket, sf::UdpSocket
+///
+////////////////////////////////////////////////////////////
similarity index 62%
rename from dependencies64/sfml/include/SFML/Window/WindowListener.hpp
rename to dependencies64/sfml/include/SFML/Network/SocketHandle.hpp
index 00c8cec47a01b0bc93c041a776e904405aa29060..83c2422f4de304ff521f193f8d3b4eb0d02162d6 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 //
 ////////////////////////////////////////////////////////////
 
-#ifndef SFML_WINDOWLISTENER_HPP
-#define SFML_WINDOWLISTENER_HPP
+#ifndef SFML_SOCKETHANDLE_HPP
+#define SFML_SOCKETHANDLE_HPP
 
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
 #include <SFML/Config.hpp>
 
+#if defined(SFML_SYSTEM_WINDOWS)
+    #include <basetsd.h>
+#endif
+
 
 namespace sf
 {
-class Event;
-
 ////////////////////////////////////////////////////////////
-/// Base class for classes that want to receive events
-/// from a window (for internal use only)
+// Define the low-level socket handle type, specific to
+// each platform
 ////////////////////////////////////////////////////////////
-class SFML_API WindowListener
-{
-public :
+#if defined(SFML_SYSTEM_WINDOWS)
+
+    typedef UINT_PTR SocketHandle;
 
-    ////////////////////////////////////////////////////////////
-    /// Called each time an event is received from attached window
-    ///
-    /// \param EventReceived : Event received
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual void OnEvent(const Event& EventReceived) = 0;
+#else
 
-protected :
+    typedef int SocketHandle;
 
-    ////////////////////////////////////////////////////////////
-    /// Destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual ~WindowListener() {}
-};
+#endif
 
 } // namespace sf
 
 
-#endif // SFML_WINDOWLISTENER_HPP
+#endif // SFML_SOCKETHANDLE_HPP
diff --git a/dependencies64/sfml/include/SFML/Network/SocketSelector.hpp b/dependencies64/sfml/include/SFML/Network/SocketSelector.hpp
new file mode 100644 (file)
index 0000000..336b301
--- /dev/null
@@ -0,0 +1,263 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETSELECTOR_HPP
+#define SFML_SOCKETSELECTOR_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/System/Time.hpp>
+
+
+namespace sf
+{
+class Socket;
+
+////////////////////////////////////////////////////////////
+/// \brief Multiplexer that allows to read from multiple sockets
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API SocketSelector
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    SocketSelector();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Copy constructor
+    ///
+    /// \param copy Instance to copy
+    ///
+    ////////////////////////////////////////////////////////////
+    SocketSelector(const SocketSelector& copy);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    ~SocketSelector();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Add a new socket to the selector
+    ///
+    /// This function keeps a weak reference to the socket,
+    /// so you have to make sure that the socket is not destroyed
+    /// while it is stored in the selector.
+    /// This function does nothing if the socket is not valid.
+    ///
+    /// \param socket Reference to the socket to add
+    ///
+    /// \see remove, clear
+    ///
+    ////////////////////////////////////////////////////////////
+    void add(Socket& socket);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Remove a socket from the selector
+    ///
+    /// This function doesn't destroy the socket, it simply
+    /// removes the reference that the selector has to it.
+    ///
+    /// \param socket Reference to the socket to remove
+    ///
+    /// \see add, clear
+    ///
+    ////////////////////////////////////////////////////////////
+    void remove(Socket& socket);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Remove all the sockets stored in the selector
+    ///
+    /// This function doesn't destroy any instance, it simply
+    /// removes all the references that the selector has to
+    /// external sockets.
+    ///
+    /// \see add, remove
+    ///
+    ////////////////////////////////////////////////////////////
+    void clear();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Wait until one or more sockets are ready to receive
+    ///
+    /// This function returns as soon as at least one socket has
+    /// some data available to be received. To know which sockets are
+    /// ready, use the isReady function.
+    /// If you use a timeout and no socket is ready before the timeout
+    /// is over, the function returns false.
+    ///
+    /// \param timeout Maximum time to wait, (use Time::Zero for infinity)
+    ///
+    /// \return True if there are sockets ready, false otherwise
+    ///
+    /// \see isReady
+    ///
+    ////////////////////////////////////////////////////////////
+    bool wait(Time timeout = Time::Zero);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Test a socket to know if it is ready to receive data
+    ///
+    /// This function must be used after a call to Wait, to know
+    /// which sockets are ready to receive data. If a socket is
+    /// ready, a call to receive will never block because we know
+    /// that there is data available to read.
+    /// Note that if this function returns true for a TcpListener,
+    /// this means that it is ready to accept a new connection.
+    ///
+    /// \param socket Socket to test
+    ///
+    /// \return True if the socket is ready to read, false otherwise
+    ///
+    /// \see isReady
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isReady(Socket& socket) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of assignment operator
+    ///
+    /// \param right Instance to assign
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    SocketSelector& operator =(const SocketSelector& right);
+
+private:
+
+    struct SocketSelectorImpl;
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    SocketSelectorImpl* m_impl; ///< Opaque pointer to the implementation (which requires OS-specific types)
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETSELECTOR_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::SocketSelector
+/// \ingroup network
+///
+/// Socket selectors provide a way to wait until some data is
+/// available on a set of sockets, instead of just one. This
+/// is convenient when you have multiple sockets that may
+/// possibly receive data, but you don't know which one will
+/// be ready first. In particular, it avoids to use a thread
+/// for each socket; with selectors, a single thread can handle
+/// all the sockets.
+///
+/// All types of sockets can be used in a selector:
+/// \li sf::TcpListener
+/// \li sf::TcpSocket
+/// \li sf::UdpSocket
+///
+/// A selector doesn't store its own copies of the sockets
+/// (socket classes are not copyable anyway), it simply keeps
+/// a reference to the original sockets that you pass to the
+/// "add" function. Therefore, you can't use the selector as a
+/// socket container, you must store them outside and make sure
+/// that they are alive as long as they are used in the selector.
+///
+/// Using a selector is simple:
+/// \li populate the selector with all the sockets that you want to observe
+/// \li make it wait until there is data available on any of the sockets
+/// \li test each socket to find out which ones are ready
+///
+/// Usage example:
+/// \code
+/// // Create a socket to listen to new connections
+/// sf::TcpListener listener;
+/// listener.listen(55001);
+///
+/// // Create a list to store the future clients
+/// std::list<sf::TcpSocket*> clients;
+///
+/// // Create a selector
+/// sf::SocketSelector selector;
+///
+/// // Add the listener to the selector
+/// selector.add(listener);
+///
+/// // Endless loop that waits for new connections
+/// while (running)
+/// {
+///     // Make the selector wait for data on any socket
+///     if (selector.wait())
+///     {
+///         // Test the listener
+///         if (selector.isReady(listener))
+///         {
+///             // The listener is ready: there is a pending connection
+///             sf::TcpSocket* client = new sf::TcpSocket;
+///             if (listener.accept(*client) == sf::Socket::Done)
+///             {
+///                 // Add the new client to the clients list
+///                 clients.push_back(client);
+///
+///                 // Add the new client to the selector so that we will
+///                 // be notified when he sends something
+///                 selector.add(*client);
+///             }
+///             else
+///             {
+///                 // Error, we won't get a new connection, delete the socket
+///                 delete client;
+///             }
+///         }
+///         else
+///         {
+///             // The listener socket is not ready, test all other sockets (the clients)
+///             for (std::list<sf::TcpSocket*>::iterator it = clients.begin(); it != clients.end(); ++it)
+///             {
+///                 sf::TcpSocket& client = **it;
+///                 if (selector.isReady(client))
+///                 {
+///                     // The client has sent some data, we can receive it
+///                     sf::Packet packet;
+///                     if (client.receive(packet) == sf::Socket::Done)
+///                     {
+///                         ...
+///                     }
+///                 }
+///             }
+///         }
+///     }
+/// }
+/// \endcode
+///
+/// \see sf::Socket
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/TcpListener.hpp b/dependencies64/sfml/include/SFML/Network/TcpListener.hpp
new file mode 100644 (file)
index 0000000..db93a6c
--- /dev/null
@@ -0,0 +1,162 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TCPLISTENER_HPP
+#define SFML_TCPLISTENER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/Network/Socket.hpp>
+
+
+namespace sf
+{
+class TcpSocket;
+
+////////////////////////////////////////////////////////////
+/// \brief Socket that listens to new TCP connections
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API TcpListener : public Socket
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    TcpListener();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the port to which the socket is bound locally
+    ///
+    /// If the socket is not listening to a port, this function
+    /// returns 0.
+    ///
+    /// \return Port to which the socket is bound
+    ///
+    /// \see listen
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned short getLocalPort() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Start listening for connections
+    ///
+    /// This functions makes the socket listen to the specified
+    /// port, waiting for new connections.
+    /// If the socket was previously listening to another port,
+    /// it will be stopped first and bound to the new port.
+    ///
+    /// \param port Port to listen for new connections
+    ///
+    /// \return Status code
+    ///
+    /// \see accept, close
+    ///
+    ////////////////////////////////////////////////////////////
+    Status listen(unsigned short port);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Stop listening and close the socket
+    ///
+    /// This function gracefully stops the listener. If the
+    /// socket is not listening, this function has no effect.
+    ///
+    /// \see listen
+    ///
+    ////////////////////////////////////////////////////////////
+    void close();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Accept a new connection
+    ///
+    /// If the socket is in blocking mode, this function will
+    /// not return until a connection is actually received.
+    ///
+    /// \param socket Socket that will hold the new connection
+    ///
+    /// \return Status code
+    ///
+    /// \see listen
+    ///
+    ////////////////////////////////////////////////////////////
+    Status accept(TcpSocket& socket);
+};
+
+
+} // namespace sf
+
+
+#endif // SFML_TCPLISTENER_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::TcpListener
+/// \ingroup network
+///
+/// A listener socket is a special type of socket that listens to
+/// a given port and waits for connections on that port.
+/// This is all it can do.
+///
+/// When a new connection is received, you must call accept and
+/// the listener returns a new instance of sf::TcpSocket that
+/// is properly initialized and can be used to communicate with
+/// the new client.
+///
+/// Listener sockets are specific to the TCP protocol,
+/// UDP sockets are connectionless and can therefore communicate
+/// directly. As a consequence, a listener socket will always
+/// return the new connections as sf::TcpSocket instances.
+///
+/// A listener is automatically closed on destruction, like all
+/// other types of socket. However if you want to stop listening
+/// before the socket is destroyed, you can call its close()
+/// function.
+///
+/// Usage example:
+/// \code
+/// // Create a listener socket and make it wait for new
+/// // connections on port 55001
+/// sf::TcpListener listener;
+/// listener.listen(55001);
+///
+/// // Endless loop that waits for new connections
+/// while (running)
+/// {
+///     sf::TcpSocket client;
+///     if (listener.accept(client) == sf::Socket::Done)
+///     {
+///         // A new client just connected!
+///         std::cout << "New connection received from " << client.getRemoteAddress() << std::endl;
+///         doSomethingWith(client);
+///     }
+/// }
+/// \endcode
+///
+/// \see sf::TcpSocket, sf::Socket
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/TcpSocket.hpp b/dependencies64/sfml/include/SFML/Network/TcpSocket.hpp
new file mode 100644 (file)
index 0000000..03a69ec
--- /dev/null
@@ -0,0 +1,292 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TCPSOCKET_HPP
+#define SFML_TCPSOCKET_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/Network/Socket.hpp>
+#include <SFML/System/Time.hpp>
+
+
+namespace sf
+{
+class TcpListener;
+class IpAddress;
+class Packet;
+
+////////////////////////////////////////////////////////////
+/// \brief Specialized socket using the TCP protocol
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API TcpSocket : public Socket
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    TcpSocket();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the port to which the socket is bound locally
+    ///
+    /// If the socket is not connected, this function returns 0.
+    ///
+    /// \return Port to which the socket is bound
+    ///
+    /// \see connect, getRemotePort
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned short getLocalPort() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the address of the connected peer
+    ///
+    /// It the socket is not connected, this function returns
+    /// sf::IpAddress::None.
+    ///
+    /// \return Address of the remote peer
+    ///
+    /// \see getRemotePort
+    ///
+    ////////////////////////////////////////////////////////////
+    IpAddress getRemoteAddress() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the port of the connected peer to which
+    ///        the socket is connected
+    ///
+    /// If the socket is not connected, this function returns 0.
+    ///
+    /// \return Remote port to which the socket is connected
+    ///
+    /// \see getRemoteAddress
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned short getRemotePort() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Connect the socket to a remote peer
+    ///
+    /// In blocking mode, this function may take a while, especially
+    /// if the remote peer is not reachable. The last parameter allows
+    /// you to stop trying to connect after a given timeout.
+    /// If the socket was previously connected, it is first disconnected.
+    ///
+    /// \param remoteAddress Address of the remote peer
+    /// \param remotePort    Port of the remote peer
+    /// \param timeout       Optional maximum time to wait
+    ///
+    /// \return Status code
+    ///
+    /// \see disconnect
+    ///
+    ////////////////////////////////////////////////////////////
+    Status connect(const IpAddress& remoteAddress, unsigned short remotePort, Time timeout = Time::Zero);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Disconnect the socket from its remote peer
+    ///
+    /// This function gracefully closes the connection. If the
+    /// socket is not connected, this function has no effect.
+    ///
+    /// \see connect
+    ///
+    ////////////////////////////////////////////////////////////
+    void disconnect();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send raw data to the remote peer
+    ///
+    /// This function will fail if the socket is not connected.
+    ///
+    /// \param data Pointer to the sequence of bytes to send
+    /// \param size Number of bytes to send
+    ///
+    /// \return Status code
+    ///
+    /// \see receive
+    ///
+    ////////////////////////////////////////////////////////////
+    Status send(const void* data, std::size_t size);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Receive raw data from the remote peer
+    ///
+    /// In blocking mode, this function will wait until some
+    /// bytes are actually received.
+    /// This function will fail if the socket is not connected.
+    ///
+    /// \param data     Pointer to the array to fill with the received bytes
+    /// \param size     Maximum number of bytes that can be received
+    /// \param received This variable is filled with the actual number of bytes received
+    ///
+    /// \return Status code
+    ///
+    /// \see send
+    ///
+    ////////////////////////////////////////////////////////////
+    Status receive(void* data, std::size_t size, std::size_t& received);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send a formatted packet of data to the remote peer
+    ///
+    /// This function will fail if the socket is not connected.
+    ///
+    /// \param packet Packet to send
+    ///
+    /// \return Status code
+    ///
+    /// \see receive
+    ///
+    ////////////////////////////////////////////////////////////
+    Status send(Packet& packet);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Receive a formatted packet of data from the remote peer
+    ///
+    /// In blocking mode, this function will wait until the whole packet
+    /// has been received.
+    /// This function will fail if the socket is not connected.
+    ///
+    /// \param packet Packet to fill with the received data
+    ///
+    /// \return Status code
+    ///
+    /// \see send
+    ///
+    ////////////////////////////////////////////////////////////
+    Status receive(Packet& packet);
+
+private:
+
+    friend class TcpListener;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Structure holding the data of a pending packet
+    ///
+    ////////////////////////////////////////////////////////////
+    struct PendingPacket
+    {
+        PendingPacket();
+
+        Uint32            Size;         ///< Data of packet size
+        std::size_t       SizeReceived; ///< Number of size bytes received so far
+        std::vector<char> Data;         ///< Data of the packet
+    };
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    PendingPacket m_pendingPacket; ///< Temporary data of the packet currently being received
+};
+
+} // namespace sf
+
+
+#endif // SFML_TCPSOCKET_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::TcpSocket
+/// \ingroup network
+///
+/// TCP is a connected protocol, which means that a TCP
+/// socket can only communicate with the host it is connected
+/// to. It can't send or receive anything if it is not connected.
+///
+/// The TCP protocol is reliable but adds a slight overhead.
+/// It ensures that your data will always be received in order
+/// and without errors (no data corrupted, lost or duplicated).
+///
+/// When a socket is connected to a remote host, you can
+/// retrieve informations about this host with the
+/// getRemoteAddress and getRemotePort functions. You can
+/// also get the local port to which the socket is bound
+/// (which is automatically chosen when the socket is connected),
+/// with the getLocalPort function.
+///
+/// Sending and receiving data can use either the low-level
+/// or the high-level functions. The low-level functions
+/// process a raw sequence of bytes, and cannot ensure that
+/// one call to Send will exactly match one call to Receive
+/// at the other end of the socket.
+///
+/// The high-level interface uses packets (see sf::Packet),
+/// which are easier to use and provide more safety regarding
+/// the data that is exchanged. You can look at the sf::Packet
+/// class to get more details about how they work.
+///
+/// The socket is automatically disconnected when it is destroyed,
+/// but if you want to explicitly close the connection while
+/// the socket instance is still alive, you can call disconnect.
+///
+/// Usage example:
+/// \code
+/// // ----- The client -----
+///
+/// // Create a socket and connect it to 192.168.1.50 on port 55001
+/// sf::TcpSocket socket;
+/// socket.connect("192.168.1.50", 55001);
+///
+/// // Send a message to the connected host
+/// std::string message = "Hi, I am a client";
+/// socket.send(message.c_str(), message.size() + 1);
+///
+/// // Receive an answer from the server
+/// char buffer[1024];
+/// std::size_t received = 0;
+/// socket.receive(buffer, sizeof(buffer), received);
+/// std::cout << "The server said: " << buffer << std::endl;
+///
+/// // ----- The server -----
+///
+/// // Create a listener to wait for incoming connections on port 55001
+/// sf::TcpListener listener;
+/// listener.listen(55001);
+///
+/// // Wait for a connection
+/// sf::TcpSocket socket;
+/// listener.accept(socket);
+/// std::cout << "New client connected: " << socket.getRemoteAddress() << std::endl;
+///
+/// // Receive a message from the client
+/// char buffer[1024];
+/// std::size_t received = 0;
+/// socket.receive(buffer, sizeof(buffer), received);
+/// std::cout << "The client said: " << buffer << std::endl;
+///
+/// // Send an answer
+/// std::string message = "Welcome, client";
+/// socket.send(message.c_str(), message.size() + 1);
+/// \endcode
+///
+/// \see sf::Socket, sf::UdpSocket, sf::Packet
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Network/UdpSocket.hpp b/dependencies64/sfml/include/SFML/Network/UdpSocket.hpp
new file mode 100644 (file)
index 0000000..268edd0
--- /dev/null
@@ -0,0 +1,283 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_UDPSOCKET_HPP
+#define SFML_UDPSOCKET_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/Export.hpp>
+#include <SFML/Network/Socket.hpp>
+#include <vector>
+
+
+namespace sf
+{
+class IpAddress;
+class Packet;
+
+////////////////////////////////////////////////////////////
+/// \brief Specialized socket using the UDP protocol
+///
+////////////////////////////////////////////////////////////
+class SFML_NETWORK_API UdpSocket : public Socket
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    // Constants
+    ////////////////////////////////////////////////////////////
+    enum
+    {
+        MaxDatagramSize = 65507 ///< The maximum number of bytes that can be sent in a single UDP datagram
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    UdpSocket();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the port to which the socket is bound locally
+    ///
+    /// If the socket is not bound to a port, this function
+    /// returns 0.
+    ///
+    /// \return Port to which the socket is bound
+    ///
+    /// \see bind
+    ///
+    ////////////////////////////////////////////////////////////
+    unsigned short getLocalPort() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Bind the socket to a specific port
+    ///
+    /// Binding the socket to a port is necessary for being
+    /// able to receive data on that port.
+    /// You can use the special value Socket::AnyPort to tell the
+    /// system to automatically pick an available port, and then
+    /// call getLocalPort to retrieve the chosen port.
+    ///
+    /// \param port Port to bind the socket to
+    ///
+    /// \return Status code
+    ///
+    /// \see unbind, getLocalPort
+    ///
+    ////////////////////////////////////////////////////////////
+    Status bind(unsigned short port);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Unbind the socket from the local port to which it is bound
+    ///
+    /// The port that the socket was previously using is immediately
+    /// available after this function is called. If the
+    /// socket is not bound to a port, this function has no effect.
+    ///
+    /// \see bind
+    ///
+    ////////////////////////////////////////////////////////////
+    void unbind();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send raw data to a remote peer
+    ///
+    /// Make sure that \a size is not greater than
+    /// UdpSocket::MaxDatagramSize, otherwise this function will
+    /// fail and no data will be sent.
+    ///
+    /// \param data          Pointer to the sequence of bytes to send
+    /// \param size          Number of bytes to send
+    /// \param remoteAddress Address of the receiver
+    /// \param remotePort    Port of the receiver to send the data to
+    ///
+    /// \return Status code
+    ///
+    /// \see receive
+    ///
+    ////////////////////////////////////////////////////////////
+    Status send(const void* data, std::size_t size, const IpAddress& remoteAddress, unsigned short remotePort);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Receive raw data from a remote peer
+    ///
+    /// In blocking mode, this function will wait until some
+    /// bytes are actually received.
+    /// Be careful to use a buffer which is large enough for
+    /// the data that you intend to receive, if it is too small
+    /// then an error will be returned and *all* the data will
+    /// be lost.
+    ///
+    /// \param data          Pointer to the array to fill with the received bytes
+    /// \param size          Maximum number of bytes that can be received
+    /// \param received      This variable is filled with the actual number of bytes received
+    /// \param remoteAddress Address of the peer that sent the data
+    /// \param remotePort    Port of the peer that sent the data
+    ///
+    /// \return Status code
+    ///
+    /// \see send
+    ///
+    ////////////////////////////////////////////////////////////
+    Status receive(void* data, std::size_t size, std::size_t& received, IpAddress& remoteAddress, unsigned short& remotePort);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Send a formatted packet of data to a remote peer
+    ///
+    /// Make sure that the packet size is not greater than
+    /// UdpSocket::MaxDatagramSize, otherwise this function will
+    /// fail and no data will be sent.
+    ///
+    /// \param packet        Packet to send
+    /// \param remoteAddress Address of the receiver
+    /// \param remotePort    Port of the receiver to send the data to
+    ///
+    /// \return Status code
+    ///
+    /// \see receive
+    ///
+    ////////////////////////////////////////////////////////////
+    Status send(Packet& packet, const IpAddress& remoteAddress, unsigned short remotePort);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Receive a formatted packet of data from a remote peer
+    ///
+    /// In blocking mode, this function will wait until the whole packet
+    /// has been received.
+    ///
+    /// \param packet        Packet to fill with the received data
+    /// \param remoteAddress Address of the peer that sent the data
+    /// \param remotePort    Port of the peer that sent the data
+    ///
+    /// \return Status code
+    ///
+    /// \see send
+    ///
+    ////////////////////////////////////////////////////////////
+    Status receive(Packet& packet, IpAddress& remoteAddress, unsigned short& remotePort);
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    std::vector<char> m_buffer; ///< Temporary buffer holding the received data in Receive(Packet)
+};
+
+} // namespace sf
+
+
+#endif // SFML_UDPSOCKET_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::UdpSocket
+/// \ingroup network
+///
+/// A UDP socket is a connectionless socket. Instead of
+/// connecting once to a remote host, like TCP sockets,
+/// it can send to and receive from any host at any time.
+///
+/// It is a datagram protocol: bounded blocks of data (datagrams)
+/// are transfered over the network rather than a continuous
+/// stream of data (TCP). Therefore, one call to send will always
+/// match one call to receive (if the datagram is not lost),
+/// with the same data that was sent.
+/// 
+/// The UDP protocol is lightweight but unreliable. Unreliable
+/// means that datagrams may be duplicated, be lost or
+/// arrive reordered. However, if a datagram arrives, its
+/// data is guaranteed to be valid.
+///
+/// UDP is generally used for real-time communication
+/// (audio or video streaming, real-time games, etc.) where
+/// speed is crucial and lost data doesn't matter much.
+///
+/// Sending and receiving data can use either the low-level
+/// or the high-level functions. The low-level functions
+/// process a raw sequence of bytes, whereas the high-level
+/// interface uses packets (see sf::Packet), which are easier
+/// to use and provide more safety regarding the data that is
+/// exchanged. You can look at the sf::Packet class to get
+/// more details about how they work.
+///
+/// It is important to note that UdpSocket is unable to send
+/// datagrams bigger than MaxDatagramSize. In this case, it
+/// returns an error and doesn't send anything. This applies
+/// to both raw data and packets. Indeed, even packets are
+/// unable to split and recompose data, due to the unreliability
+/// of the protocol (dropped, mixed or duplicated datagrams may
+/// lead to a big mess when trying to recompose a packet).
+///
+/// If the socket is bound to a port, it is automatically
+/// unbound from it when the socket is destroyed. However,
+/// you can unbind the socket explicitly with the Unbind
+/// function if necessary, to stop receiving messages or
+/// make the port available for other sockets.
+///
+/// Usage example:
+/// \code
+/// // ----- The client -----
+///
+/// // Create a socket and bind it to the port 55001
+/// sf::UdpSocket socket;
+/// socket.bind(55001);
+///
+/// // Send a message to 192.168.1.50 on port 55002
+/// std::string message = "Hi, I am " + sf::IpAddress::getLocalAddress().toString();
+/// socket.send(message.c_str(), message.size() + 1, "192.168.1.50", 55002);
+///
+/// // Receive an answer (most likely from 192.168.1.50, but could be anyone else)
+/// char buffer[1024];
+/// std::size_t received = 0;
+/// sf::IpAddress sender;
+/// unsigned short port;
+/// socket.receive(buffer, sizeof(buffer), received, sender, port);
+/// std::cout << sender.ToString() << " said: " << buffer << std::endl;
+///
+/// // ----- The server -----
+///
+/// // Create a socket and bind it to the port 55002
+/// sf::UdpSocket socket;
+/// socket.bind(55002);
+///
+/// // Receive a message from anyone
+/// char buffer[1024];
+/// std::size_t received = 0;
+/// sf::IpAddress sender;
+/// unsigned short port;
+/// socket.receive(buffer, sizeof(buffer), received, sender, port);
+/// std::cout << sender.ToString() << " said: " << buffer << std::endl;
+///
+/// // Send an answer
+/// std::string message = "Welcome " + sender.toString();
+/// socket.send(message.c_str(), message.size() + 1, sender, port);
+/// \endcode
+///
+/// \see sf::Socket, sf::TcpSocket, sf::Packet
+///
+////////////////////////////////////////////////////////////
similarity index 75%
rename from dependencies64/sfml/include/SFML/Window/OpenGL.hpp
rename to dependencies64/sfml/include/SFML/OpenGL.hpp
index 45344bcaaec22beedcb54abbdffd10458b9ee1a3..00bdd8eb05c1930c7e74e64a25d8ff6816a053ff 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 #if defined(SFML_SYSTEM_WINDOWS)
 
-    #include <windows.h>
+    // The Visual C++ version of gl.h uses WINGDIAPI and APIENTRY but doesn't define them
+    #ifdef _MSC_VER
+        #include <windows.h>
+    #endif
+
     #include <GL/gl.h>
     #include <GL/glu.h>
 
 #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
 
-    #include <GL/gl.h>
-    #include <GL/glu.h>
+    #if defined(SFML_OPENGL_ES)
+        #include <GLES/gl.h>
+        #include <GLES/glext.h>
+    #else
+        #include <GL/gl.h>
+        #include <GL/glu.h>
+    #endif
 
 #elif defined(SFML_SYSTEM_MACOS)
 
     #include <OpenGL/gl.h>
     #include <OpenGL/glu.h>
 
+#elif defined (SFML_SYSTEM_IOS)
+
+    #include <OpenGLES/ES1/gl.h>
+    #include <OpenGLES/ES1/glext.h>
+
+#elif defined (SFML_SYSTEM_ANDROID)
+
+    #include <GLES/gl.h>
+    #include <GLES/glext.h>
+
 #endif
 
 
 #endif // SFML_OPENGL_HPP
-
index 0a1eac9b10b758e936b0e2cf359b5c3a15648e86..eca81a33ff3006712a2218f0ad4bc7ef6cf519ad 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 
 #include <SFML/Config.hpp>
 #include <SFML/System/Clock.hpp>
+#include <SFML/System/Err.hpp>
+#include <SFML/System/InputStream.hpp>
 #include <SFML/System/Lock.hpp>
 #include <SFML/System/Mutex.hpp>
-#include <SFML/System/Randomizer.hpp>
 #include <SFML/System/Sleep.hpp>
+#include <SFML/System/String.hpp>
 #include <SFML/System/Thread.hpp>
-#include <SFML/System/Unicode.hpp>
+#include <SFML/System/ThreadLocal.hpp>
+#include <SFML/System/ThreadLocalPtr.hpp>
+#include <SFML/System/Utf.hpp>
 #include <SFML/System/Vector2.hpp>
 #include <SFML/System/Vector3.hpp>
 
 #endif // SFML_SYSTEM_HPP
+
+////////////////////////////////////////////////////////////
+/// \defgroup system System module
+///
+/// Base module of SFML, defining various utilities. It provides
+/// vector classes, Unicode strings and conversion functions,
+/// threads and mutexes, timing classes.
+/// 
+////////////////////////////////////////////////////////////
index f91c3dc7c52cb462b2821f5ca33058f7f37ff7d6..1ff63cb4238cc692cf0b5ecaa67d9148a08f9853 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/System/Export.hpp>
+#include <SFML/System/Time.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Clock is an utility class for manipulating time
+/// \brief Utility class that measures the elapsed time
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Clock
+class SFML_SYSTEM_API Clock
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// The clock starts automatically after being constructed.
     ///
     ////////////////////////////////////////////////////////////
     Clock();
 
     ////////////////////////////////////////////////////////////
-    /// Get the time elapsed since last reset
+    /// \brief Get the elapsed time
+    ///
+    /// This function returns the time elapsed since the last call
+    /// to restart() (or the construction of the instance if restart()
+    /// has not been called).
     ///
-    /// \return Time elapsed, in seconds
+    /// \return Time elapsed
     ///
     ////////////////////////////////////////////////////////////
-    float GetElapsedTime() const;
+    Time getElapsedTime() const;
 
     ////////////////////////////////////////////////////////////
-    /// Restart the timer
+    /// \brief Restart the clock
+    ///
+    /// This function puts the time counter back to zero.
+    /// It also returns the time elapsed since the clock was started.
+    ///
+    /// \return Time elapsed
     ///
     ////////////////////////////////////////////////////////////
-    void Reset();
+    Time restart();
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    double myStartTime; ///< Time of last reset
+    Time m_startTime; ///< Time of last reset, in microseconds
 };
 
 } // namespace sf
 
 
 #endif // SFML_CLOCK_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Clock
+/// \ingroup system
+///
+/// sf::Clock is a lightweight class for measuring time.
+///
+/// Its provides the most precise time that the underlying
+/// OS can achieve (generally microseconds or nanoseconds).
+/// It also ensures monotonicity, which means that the returned
+/// time can never go backward, even if the system time is
+/// changed.
+///
+/// Usage example:
+/// \code
+/// sf::Clock clock;
+/// ...
+/// Time time1 = clock.getElapsedTime();
+/// ...
+/// Time time2 = clock.restart();
+/// \endcode
+///
+/// The sf::Time value returned by the clock can then be
+/// converted to a number of seconds, milliseconds or even
+/// microseconds.
+///
+/// \see sf::Time
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/Err.hpp b/dependencies64/sfml/include/SFML/System/Err.hpp
new file mode 100644 (file)
index 0000000..74d56f2
--- /dev/null
@@ -0,0 +1,80 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_ERR_HPP
+#define SFML_ERR_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/Export.hpp>
+#include <ostream>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Standard stream used by SFML to output warnings and errors
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API std::ostream& err();
+
+} // namespace sf
+
+
+#endif // SFML_ERR_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \fn sf::err
+/// \ingroup system
+///
+/// By default, sf::err() outputs to the same location as std::cerr,
+/// (-> the stderr descriptor) which is the console if there's
+/// one available.
+///
+/// It is a standard std::ostream instance, so it supports all the
+/// insertion operations defined by the STL
+/// (operator <<, manipulators, etc.).
+///
+/// sf::err() can be redirected to write to another output, independently
+/// of std::cerr, by using the rdbuf() function provided by the
+/// std::ostream class.
+///
+/// Example:
+/// \code
+/// // Redirect to a file
+/// std::ofstream file("sfml-log.txt");
+/// std::streambuf* previous = sf::err().rdbuf(file.rdbuf());
+///
+/// // Redirect to nothing
+/// sf::err().rdbuf(NULL);
+///
+/// // Restore the original output
+/// sf::err().rdbuf(previous);
+/// \endcode
+///
+/// \return Reference to std::ostream representing the SFML error stream
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/Export.hpp b/dependencies64/sfml/include/SFML/System/Export.hpp
new file mode 100644 (file)
index 0000000..ba52091
--- /dev/null
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SYSTEM_EXPORT_HPP
+#define SFML_SYSTEM_EXPORT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_SYSTEM_EXPORTS)
+
+    #define SFML_SYSTEM_API SFML_API_EXPORT
+
+#else
+
+    #define SFML_SYSTEM_API SFML_API_IMPORT
+
+#endif
+
+
+#endif // SFML_SYSTEM_EXPORT_HPP
diff --git a/dependencies64/sfml/include/SFML/System/InputStream.hpp b/dependencies64/sfml/include/SFML/System/InputStream.hpp
new file mode 100644 (file)
index 0000000..ccf1d9f
--- /dev/null
@@ -0,0 +1,151 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_INPUTSTREAM_HPP
+#define SFML_INPUTSTREAM_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Abstract class for custom file input streams
+///
+////////////////////////////////////////////////////////////
+class InputStream
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Virtual destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual ~InputStream() {}
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Read data from the stream
+    ///
+    /// After reading, the stream's reading position must be
+    /// advanced by the amount of bytes read.
+    ///
+    /// \param data Buffer where to copy the read data
+    /// \param size Desired number of bytes to read
+    ///
+    /// \return The number of bytes actually read, or -1 on error
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Int64 read(void* data, Int64 size) = 0;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change the current reading position
+    ///
+    /// \param position The position to seek to, from the beginning
+    ///
+    /// \return The position actually sought to, or -1 on error
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Int64 seek(Int64 position) = 0;
+    
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current reading position in the stream
+    ///
+    /// \return The current position, or -1 on error.
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Int64 tell() = 0;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the size of the stream
+    ///
+    /// \return The total number of bytes available in the stream, or -1 on error
+    ///
+    ////////////////////////////////////////////////////////////
+    virtual Int64 getSize() = 0;
+};
+
+} // namespace sf
+
+
+#endif // SFML_INPUTSTREAM_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::InputStream
+/// \ingroup system
+///
+/// This class allows users to define their own file input sources
+/// from which SFML can load resources.
+///
+/// SFML resource classes like sf::Texture and
+/// sf::SoundBuffer provide loadFromFile and loadFromMemory functions,
+/// which read data from conventional sources. However, if you
+/// have data coming from a different source (over a network,
+/// embedded, encrypted, compressed, etc) you can derive your
+/// own class from sf::InputStream and load SFML resources with
+/// their loadFromStream function.
+///
+/// Usage example:
+/// \code
+/// // custom stream class that reads from inside a zip file
+/// class ZipStream : public sf::InputStream
+/// {
+/// public:
+/// 
+///     ZipStream(std::string archive);
+///
+///     bool open(std::string filename);
+///
+///     Int64 read(void* data, Int64 size);
+/// 
+///     Int64 seek(Int64 position);
+///     
+///     Int64 tell();
+/// 
+///     Int64 getSize();
+///
+/// private:
+///
+///     ...
+/// };
+///
+/// // now you can load textures...
+/// sf::Texture texture;
+/// ZipStream stream("resources.zip");
+/// stream.open("images/img.png");
+/// texture.loadFromStream(stream);
+///
+/// // musics...
+/// sf::Music music;
+/// ZipStream stream("resources.zip");
+/// stream.open("musics/msc.ogg");
+/// music.openFromStream(stream);
+///
+/// // etc.
+/// \endcode
+///
+////////////////////////////////////////////////////////////
index 1956e6a79f6787c7748237ade59f59949e8da1f9..1eec3428f154fcb8efa0aac6ebfb994335925cef 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
@@ -28,6 +28,7 @@
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
+#include <SFML/System/Export.hpp>
 #include <SFML/System/NonCopyable.hpp>
 
 
@@ -36,36 +37,103 @@ namespace sf
 class Mutex;
 
 ////////////////////////////////////////////////////////////
-/// Lock is an exception-safe automatic wrapper for
-/// locking and unlocking mutexes
+/// \brief Automatic wrapper for locking and unlocking mutexes
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Lock : NonCopyable
+class SFML_SYSTEM_API Lock : NonCopyable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Construct the lock with a target mutex (lock it)
+    /// \brief Construct the lock with a target mutex
     ///
-    /// @param Mutex : Mutex to lock
+    /// The mutex passed to sf::Lock is automatically locked.
+    ///
+    /// \param mutex Mutex to lock
     ///
     ////////////////////////////////////////////////////////////
-    Lock(Mutex& Mutex);
+    explicit Lock(Mutex& mutex);
 
     ////////////////////////////////////////////////////////////
-    /// Destructor (unlocks the mutex)
+    /// \brief Destructor
+    ///
+    /// The destructor of sf::Lock automatically unlocks its mutex.
     ///
     ////////////////////////////////////////////////////////////
     ~Lock();
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    Mutex& myMutex; ///< Mutex to lock / unlock
+    Mutex& m_mutex; ///< Mutex to lock / unlock
 };
 
 } // namespace sf
 
 
 #endif // SFML_LOCK_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Lock
+/// \ingroup system
+///
+/// sf::Lock is a RAII wrapper for sf::Mutex. By unlocking
+/// it in its destructor, it ensures that the mutex will
+/// always be released when the current scope (most likely
+/// a function) ends.
+/// This is even more important when an exception or an early
+/// return statement can interrupt the execution flow of the
+/// function.
+///
+/// For maximum robustness, sf::Lock should always be used
+/// to lock/unlock a mutex.
+///
+/// Usage example:
+/// \code
+/// sf::Mutex mutex;
+/// 
+/// void function()
+/// {
+///     sf::Lock lock(mutex); // mutex is now locked
+/// 
+///     functionThatMayThrowAnException(); // mutex is unlocked if this function throws
+/// 
+///     if (someCondition)
+///         return; // mutex is unlocked
+/// 
+/// } // mutex is unlocked
+/// \endcode
+///
+/// Because the mutex is not explicitly unlocked in the code,
+/// it may remain locked longer than needed. If the region
+/// of the code that needs to be protected by the mutex is
+/// not the entire function, a good practice is to create a
+/// smaller, inner scope so that the lock is limited to this
+/// part of the code.
+///
+/// \code
+/// sf::Mutex mutex;
+/// 
+/// void function()
+/// {
+///     {
+///       sf::Lock lock(mutex);
+///       codeThatRequiresProtection();
+/// 
+///     } // mutex is unlocked here
+/// 
+///     codeThatDoesntCareAboutTheMutex();
+/// }
+/// \endcode
+///
+/// Having a mutex locked longer than required is a bad practice
+/// which can lead to bad performances. Don't forget that when
+/// a mutex is locked, other threads may be waiting doing nothing
+/// until it is released.
+///
+/// \see sf::Mutex
+///
+////////////////////////////////////////////////////////////
index ad805eac09bf4b60c756cdb4614a3d61a1819cad..2bee74dcb510151472ee30825a15a28cfc065295 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/System/Export.hpp>
+#include <SFML/System/NonCopyable.hpp>
 
 
-#ifdef SFML_SYSTEM_WINDOWS
+namespace sf
+{
+namespace priv
+{
+    class MutexImpl;
+}
 
-    #include <SFML/System/Win32/Mutex.hpp>
+////////////////////////////////////////////////////////////
+/// \brief Blocks concurrent access to shared resources
+///        from multiple threads
+///
+////////////////////////////////////////////////////////////
+class SFML_SYSTEM_API Mutex : NonCopyable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    ////////////////////////////////////////////////////////////
+    Mutex();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    ////////////////////////////////////////////////////////////
+    ~Mutex();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Lock the mutex
+    ///
+    /// If the mutex is already locked in another thread,
+    /// this call will block the execution until the mutex
+    /// is released.
+    ///
+    /// \see unlock
+    ///
+    ////////////////////////////////////////////////////////////
+    void lock();
 
-#else
+    ////////////////////////////////////////////////////////////
+    /// \brief Unlock the mutex
+    ///
+    /// \see lock
+    ///
+    ////////////////////////////////////////////////////////////
+    void unlock();
 
-    #include <SFML/System/Unix/Mutex.hpp>
+private:
 
-#endif
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    priv::MutexImpl* m_mutexImpl; ///< OS-specific implementation
+};
+
+} // namespace sf
 
 
 #endif // SFML_MUTEX_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Mutex
+/// \ingroup system
+///
+/// Mutex stands for "MUTual EXclusion". A mutex is a
+/// synchronization object, used when multiple threads are involved.
+///
+/// When you want to protect a part of the code from being accessed
+/// simultaneously by multiple threads, you typically use a
+/// mutex. When a thread is locked by a mutex, any other thread
+/// trying to lock it will be blocked until the mutex is released
+/// by the thread that locked it. This way, you can allow only
+/// one thread at a time to access a critical region of your code.
+///
+/// Usage example:
+/// \code
+/// Database database; // this is a critical resource that needs some protection
+/// sf::Mutex mutex;
+///
+/// void thread1()
+/// {
+///     mutex.lock(); // this call will block the thread if the mutex is already locked by thread2
+///     database.write(...);
+///     mutex.unlock(); // if thread2 was waiting, it will now be unblocked
+/// }
+/// 
+/// void thread2()
+/// {
+///     mutex.lock(); // this call will block the thread if the mutex is already locked by thread1
+///     database.write(...);
+///     mutex.unlock(); // if thread1 was waiting, it will now be unblocked
+/// }
+/// \endcode
+///
+/// Be very careful with mutexes. A bad usage can lead to bad problems,
+/// like deadlocks (two threads are waiting for each other and the
+/// application is globally stuck).
+///
+/// To make the usage of mutexes more robust, particularly in
+/// environments where exceptions can be thrown, you should
+/// use the helper class sf::Lock to lock/unlock mutexes.
+///
+/// SFML mutexes are recursive, which means that you can lock
+/// a mutex multiple times in the same thread without creating
+/// a deadlock. In this case, the first call to lock() behaves
+/// as usual, and the following ones have no effect.
+/// However, you must call unlock() exactly as many times as you
+/// called lock(). If you don't, the mutex won't be released.
+///
+/// \see sf::Lock
+///
+////////////////////////////////////////////////////////////
index b61e989cca3d0707e009db29ed973fa2be2771c4..e11b0d52fa4df5df1ed98ac7775ba0701e317e03 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/System/Export.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Utility base class to easily declare non-copyable classes.
-/// Just inherit from NonCopyable to get a non-copyable class
+/// \brief Utility class that makes any derived
+///        class non-copyable
+///
 ////////////////////////////////////////////////////////////
-struct SFML_API NonCopyable
+class SFML_SYSTEM_API NonCopyable
 {
-protected :
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// The default constructor won't be generated, so provide it
+    /// \brief Default constructor
+    ///
+    /// Because this class has a copy constructor, the compiler
+    /// will not automatically generate the default constructor.
+    /// That's why we must define it explicitly.
     ///
     ////////////////////////////////////////////////////////////
     NonCopyable() {}
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
-    /// Copy constructor : declare it private and don't implement
-    /// it to prevent from calling it
+    /// \brief Disabled copy constructor
+    ///
+    /// By making the copy constructor private, the compiler will
+    /// trigger an error if anyone outside tries to use it.
+    /// To prevent NonCopyable or friend classes from using it,
+    /// we also give no definition, so that the linker will
+    /// produce an error if the first protection was inefficient.
     ///
     ////////////////////////////////////////////////////////////
     NonCopyable(const NonCopyable&);
 
     ////////////////////////////////////////////////////////////
-    /// Assignment operator : declare it private and don't implement
-    /// it to prevent from calling it
+    /// \brief Disabled assignment operator
+    ///
+    /// By making the assignment operator private, the compiler will
+    /// trigger an error if anyone outside tries to use it.
+    /// To prevent NonCopyable or friend classes from using it,
+    /// we also give no definition, so that the linker will
+    /// produce an error if the first protection was inefficient.
     ///
     ////////////////////////////////////////////////////////////
     NonCopyable& operator =(const NonCopyable&);
@@ -68,3 +83,37 @@ private :
 
 
 #endif // SFML_NONCOPYABLE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::NonCopyable
+/// \ingroup system
+///
+/// This class makes its instances non-copyable, by explicitly
+/// disabling its copy constructor and its assignment operator.
+///
+/// To create a non-copyable class, simply inherit from
+/// sf::NonCopyable.
+///
+/// The type of inheritance (public or private) doesn't matter,
+/// the copy constructor and assignment operator are declared private
+/// in sf::NonCopyable so they will end up being inaccessible in both
+/// cases. Thus you can use a shorter syntax for inheriting from it
+/// (see below).
+///
+/// Usage example:
+/// \code
+/// class MyNonCopyableClass : sf::NonCopyable
+/// {
+///     ...
+/// };
+/// \endcode
+///
+/// Deciding whether the instances of a class can be copied
+/// or not is a very important design choice. You are strongly
+/// encouraged to think about it before writing a class,
+/// and to use sf::NonCopyable when necessary to prevent
+/// many potential future errors when using it. This is also
+/// a very important indication to users of your class.
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/Randomizer.hpp b/dependencies64/sfml/include/SFML/System/Randomizer.hpp
deleted file mode 100644 (file)
index b1b8d02..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_RANDOMIZER_HPP
-#define SFML_RANDOMIZER_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// Randomizer is an utility class for generating pseudo-random
-/// numbers
-////////////////////////////////////////////////////////////
-class SFML_API Randomizer
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Set the seed for the generator. Using a known seed
-    /// allows you to reproduce the same sequence of random number
-    ///
-    /// \param Seed : Number to use as the seed
-    ///
-    ////////////////////////////////////////////////////////////
-    static void SetSeed(unsigned int Seed);
-
-    ////////////////////////////////////////////////////////////
-    /// Get the seed used to generate random numbers the generator.
-    ///
-    /// \return Current seed
-    ///
-    ////////////////////////////////////////////////////////////
-    static unsigned int GetSeed();
-
-    ////////////////////////////////////////////////////////////
-    /// Get a random float number in a given range
-    ///
-    /// \return Start : Start of the range
-    /// \return End :   End of the range
-    ///
-    /// \return Random number in [Begin, End]
-    ///
-    ////////////////////////////////////////////////////////////
-    static float Random(float Begin, float End);
-
-    ////////////////////////////////////////////////////////////
-    /// Get a random integer number in a given range
-    ///
-    /// \return Start : Start of the range
-    /// \return End :   End of the range
-    ///
-    /// \return Random number in [Begin, End]
-    ///
-    ////////////////////////////////////////////////////////////
-    static int Random(int Begin, int End);
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    // Static member variables
-    ////////////////////////////////////////////////////////////
-    static unsigned int ourSeed;
-};
-
-} // namespace sf
-
-
-#endif // SFML_RANDOMIZER_HPP
diff --git a/dependencies64/sfml/include/SFML/System/Resource.hpp b/dependencies64/sfml/include/SFML/System/Resource.hpp
deleted file mode 100644 (file)
index bc5654f..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_RESOURCE_HPP
-#define SFML_RESOURCE_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <set>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-// These two classes are defined in the same header because
-// they depend on each other. And as they're template classes,
-// they must be entirely defined in header files, which
-// prevents from proper separate compiling
-////////////////////////////////////////////////////////////
-
-template <typename> class ResourcePtr;
-
-////////////////////////////////////////////////////////////
-/// Base class for every resource that needs to notify
-/// dependent classes about its destruction
-////////////////////////////////////////////////////////////
-template <typename T>
-class Resource
-{
-protected :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    Resource();
-
-    ////////////////////////////////////////////////////////////
-    /// Copy constructor
-    ///
-    /// \param Copy : Resource to copy
-    ///
-    ////////////////////////////////////////////////////////////
-    Resource(const Resource<T>& Copy);
-
-    ////////////////////////////////////////////////////////////
-    /// Destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    ~Resource();
-
-    ////////////////////////////////////////////////////////////
-    /// Assignment operator
-    ///
-    /// \param Other : Resource to copy
-    ///
-    /// \return Reference to this
-    ///
-    ////////////////////////////////////////////////////////////
-    Resource<T>& operator =(const Resource<T>& Other);
-
-private :
-
-    friend class ResourcePtr<T>;
-
-    ////////////////////////////////////////////////////////////
-    /// Connect a ResourcePtr to this resource
-    ///
-    /// \param Observer : Observer to add
-    ///
-    ////////////////////////////////////////////////////////////
-    void Connect(ResourcePtr<T>& Observer) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Disconnect a ResourcePtr from this resource
-    ///
-    /// \param Observer : Observer to remove
-    ///
-    ////////////////////////////////////////////////////////////
-    void Disconnect(ResourcePtr<T>& Observer) const;
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    mutable std::set<ResourcePtr<T>*> myObservers;
-};
-
-
-////////////////////////////////////////////////////////////
-/// Safe pointer to a T resource (inheriting from sf::Resource<T>),
-/// its pointer is automatically reseted when the resource is destroyed
-////////////////////////////////////////////////////////////
-template <typename T>
-class ResourcePtr
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    ResourcePtr();
-
-    ////////////////////////////////////////////////////////////
-    /// Construct from a raw resource
-    ///
-    /// \param Resource : Internal resource
-    ///
-    ////////////////////////////////////////////////////////////
-    ResourcePtr(const T* Resource);
-
-    ////////////////////////////////////////////////////////////
-    /// Copy constructor
-    ///
-    /// \param Copy : Instance to copy
-    ///
-    ////////////////////////////////////////////////////////////
-    ResourcePtr(const ResourcePtr<T>& Copy);
-
-    ////////////////////////////////////////////////////////////
-    /// Destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    ~ResourcePtr();
-
-    ////////////////////////////////////////////////////////////
-    /// Assignment operator from another ResourcePtr
-    ///
-    /// \param Other : Resource pointer to assign
-    ///
-    /// \return Reference to this
-    ///
-    ////////////////////////////////////////////////////////////
-    ResourcePtr<T>& operator =(const ResourcePtr<T>& Other);
-
-    ////////////////////////////////////////////////////////////
-    /// Assignment operator from a raw resource
-    ///
-    /// \param Resource : Resource to assign
-    ///
-    /// \return Reference to this
-    ///
-    ////////////////////////////////////////////////////////////
-    ResourcePtr<T>& operator =(const T* Resource);
-
-    ////////////////////////////////////////////////////////////
-    /// Cast operator to implicitely convert the resource pointer to
-    /// its raw pointer type.
-    /// This might be dangerous in the general case, but in this context
-    /// it is safe enough to define this operator
-    ///
-    /// \return Pointer to the actual resource
-    ///
-    ////////////////////////////////////////////////////////////
-    operator const T*() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Operator * overload to return a reference to the actual resource
-    ///
-    /// \return Reference to the internal resource
-    ///
-    ////////////////////////////////////////////////////////////
-    const T& operator *() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Operator -> overload to return a pointer to the actual resource
-    ///
-    /// \return Pointer to the internal resource
-    ///
-    ////////////////////////////////////////////////////////////
-    const T* operator ->() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Function called when the observed resource is about to be
-    /// destroyed
-    ///
-    ////////////////////////////////////////////////////////////
-    void OnResourceDestroyed();
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    const T* myResource; /// Pointer to the actual resource
-};
-
-#include <SFML/System/Resource.inl>
-#include <SFML/System/ResourcePtr.inl>
-
-} // namespace sf
-
-
-#endif // SFML_RESOURCE_HPP
diff --git a/dependencies64/sfml/include/SFML/System/ResourcePtr.inl b/dependencies64/sfml/include/SFML/System/ResourcePtr.inl
deleted file mode 100644 (file)
index d807077..0000000
+++ /dev/null
@@ -1,149 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////
-/// Default constructor
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>::ResourcePtr() :
-myResource(NULL)
-{
-
-}
-
-
-////////////////////////////////////////////////////////////
-/// Construct from a raw resource
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>::ResourcePtr(const T* Resource) :
-myResource(Resource)
-{
-    if (myResource)
-        myResource->Connect(*this);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Copy constructor
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>::ResourcePtr(const ResourcePtr<T>& Copy) :
-myResource(Copy.myResource)
-{
-    if (myResource)
-        myResource->Connect(*this);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Destructor
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>::~ResourcePtr()
-{
-    if (myResource)
-        myResource->Disconnect(*this);
-}
-
-
-////////////////////////////////////////////////////////////
-/// Assignment operator from another ResourcePtr
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>& ResourcePtr<T>::operator =(const ResourcePtr<T>& Other)
-{
-    if (myResource)
-        myResource->Disconnect(*this);
-
-    myResource = Other.myResource;
-
-    if (myResource)
-        myResource->Connect(*this);
-
-    return *this;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Assignment operator from a raw resource
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>& ResourcePtr<T>::operator =(const T* Resource)
-{
-    if (myResource)
-        myResource->Disconnect(*this);
-
-    myResource = Resource;
-
-    if (myResource)
-        myResource->Connect(*this);
-
-    return *this;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Cast operator to implicitely convert the resource pointer to
-/// its raw pointer type.
-/// This might be dangerous in the general case, but in this context
-/// it is safe enough to define this operator
-////////////////////////////////////////////////////////////
-template <typename T>
-ResourcePtr<T>::operator const T*() const
-{
-    return myResource;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Operator * overload to return a reference to the actual resource
-////////////////////////////////////////////////////////////
-template <typename T>
-const T& ResourcePtr<T>::operator *() const
-{
-    return *myResource;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Operator -> overload to return a pointer to the actual resource
-////////////////////////////////////////////////////////////
-template <typename T>
-const T* ResourcePtr<T>::operator ->() const
-{
-    return myResource;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Function called when the observed resource is about to be
-/// destroyed
-////////////////////////////////////////////////////////////
-template <typename T>
-void ResourcePtr<T>::OnResourceDestroyed()
-{
-    myResource = NULL;
-}
index 0aa84c01a08f2c9e4e9a90b78fe8ebd874666759..fd7fb5adffb4ba1dadb9a61e0e8772ba516f93b8 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/System/Export.hpp>
+#include <SFML/System/Time.hpp>
 
 
 namespace sf
 {
-    ////////////////////////////////////////////////////////////
-    /// Make the current thread sleep for a given time
-    ///
-    /// \param Duration : Time to sleep, in seconds (must be >= 0)
-    ///
-    ////////////////////////////////////////////////////////////
-    void SFML_API Sleep(float Duration);
+////////////////////////////////////////////////////////////
+/// \ingroup system
+/// \brief Make the current thread sleep for a given duration
+///
+/// sf::sleep is the best way to block a program or one of its
+/// threads, as it doesn't consume any CPU power.
+///
+/// \param duration Time to sleep
+///
+////////////////////////////////////////////////////////////
+void SFML_SYSTEM_API sleep(Time duration);
 
 } // namespace sf
 
diff --git a/dependencies64/sfml/include/SFML/System/String.hpp b/dependencies64/sfml/include/SFML/System/String.hpp
new file mode 100644 (file)
index 0000000..6ef4822
--- /dev/null
@@ -0,0 +1,668 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_STRING_HPP
+#define SFML_STRING_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/Export.hpp>
+#include <SFML/System/Utf.hpp>
+#include <locale>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Utility string class that automatically handles
+///        conversions between types and encodings
+///
+////////////////////////////////////////////////////////////
+class SFML_SYSTEM_API String
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    // Types
+    ////////////////////////////////////////////////////////////
+    typedef std::basic_string<Uint32>::iterator       Iterator;      ///< Iterator type
+    typedef std::basic_string<Uint32>::const_iterator ConstIterator; ///< Read-only iterator type
+
+    ////////////////////////////////////////////////////////////
+    // Static member data
+    ////////////////////////////////////////////////////////////
+    static const std::size_t InvalidPos; ///< Represents an invalid position in the string
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// This constructor creates an empty string.
+    ///
+    ////////////////////////////////////////////////////////////
+    String();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from a single ANSI character and a locale
+    ///
+    /// The source character is converted to UTF-32 according
+    /// to the given locale.
+    ///
+    /// \param ansiChar ANSI character to convert
+    /// \param locale   Locale to use for conversion
+    ///
+    ////////////////////////////////////////////////////////////
+    String(char ansiChar, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from single wide character
+    ///
+    /// \param wideChar Wide character to convert
+    ///
+    ////////////////////////////////////////////////////////////
+    String(wchar_t wideChar);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from single UTF-32 character
+    ///
+    /// \param utf32Char UTF-32 character to convert
+    ///
+    ////////////////////////////////////////////////////////////
+    String(Uint32 utf32Char);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from a null-terminated C-style ANSI string and a locale
+    ///
+    /// The source string is converted to UTF-32 according
+    /// to the given locale.
+    ///
+    /// \param ansiString ANSI string to convert
+    /// \param locale     Locale to use for conversion
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const char* ansiString, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from an ANSI string and a locale
+    ///
+    /// The source string is converted to UTF-32 according
+    /// to the given locale.
+    ///
+    /// \param ansiString ANSI string to convert
+    /// \param locale     Locale to use for conversion
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const std::string& ansiString, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from null-terminated C-style wide string
+    ///
+    /// \param wideString Wide string to convert
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const wchar_t* wideString);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from a wide string
+    ///
+    /// \param wideString Wide string to convert
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const std::wstring& wideString);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from a null-terminated C-style UTF-32 string
+    ///
+    /// \param utf32String UTF-32 string to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const Uint32* utf32String);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from an UTF-32 string
+    ///
+    /// \param utf32String UTF-32 string to assign
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const std::basic_string<Uint32>& utf32String);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Copy constructor
+    ///
+    /// \param copy Instance to copy
+    ///
+    ////////////////////////////////////////////////////////////
+    String(const String& copy);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create a new sf::String from a UTF-8 encoded string
+    ///
+    /// \param begin Forward iterator to the beginning of the UTF-8 sequence
+    /// \param end   Forward iterator to the end of the UTF-8 sequence
+    ///
+    /// \return A sf::String containing the source string
+    ///
+    /// \see fromUtf16, fromUtf32
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename T>
+    static String fromUtf8(T begin, T end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create a new sf::String from a UTF-16 encoded string
+    ///
+    /// \param begin Forward iterator to the beginning of the UTF-16 sequence
+    /// \param end   Forward iterator to the end of the UTF-16 sequence
+    ///
+    /// \return A sf::String containing the source string
+    ///
+    /// \see fromUtf8, fromUtf32
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename T>
+    static String fromUtf16(T begin, T end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Create a new sf::String from a UTF-32 encoded string
+    ///
+    /// This function is provided for consistency, it is equivalent to
+    /// using the constructors that takes a const sf::Uint32* or
+    /// a std::basic_string<sf::Uint32>.
+    ///
+    /// \param begin Forward iterator to the beginning of the UTF-32 sequence
+    /// \param end   Forward iterator to the end of the UTF-32 sequence
+    ///
+    /// \return A sf::String containing the source string
+    ///
+    /// \see fromUtf8, fromUtf16
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename T>
+    static String fromUtf32(T begin, T end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Implicit conversion operator to std::string (ANSI string)
+    ///
+    /// The current global locale is used for conversion. If you
+    /// want to explicitly specify a locale, see toAnsiString.
+    /// Characters that do not fit in the target encoding are
+    /// discarded from the returned string.
+    /// This operator is defined for convenience, and is equivalent
+    /// to calling toAnsiString().
+    ///
+    /// \return Converted ANSI string
+    ///
+    /// \see toAnsiString, operator std::wstring
+    ///
+    ////////////////////////////////////////////////////////////
+    operator std::string() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Implicit conversion operator to std::wstring (wide string)
+    ///
+    /// Characters that do not fit in the target encoding are
+    /// discarded from the returned string.
+    /// This operator is defined for convenience, and is equivalent
+    /// to calling toWideString().
+    ///
+    /// \return Converted wide string
+    ///
+    /// \see toWideString, operator std::string
+    ///
+    ////////////////////////////////////////////////////////////
+    operator std::wstring() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert the Unicode string to an ANSI string
+    ///
+    /// The UTF-32 string is converted to an ANSI string in
+    /// the encoding defined by \a locale.
+    /// Characters that do not fit in the target encoding are
+    /// discarded from the returned string.
+    ///
+    /// \param locale Locale to use for conversion
+    ///
+    /// \return Converted ANSI string
+    ///
+    /// \see toWideString, operator std::string
+    ///
+    ////////////////////////////////////////////////////////////
+    std::string toAnsiString(const std::locale& locale = std::locale()) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert the Unicode string to a wide string
+    ///
+    /// Characters that do not fit in the target encoding are
+    /// discarded from the returned string.
+    ///
+    /// \return Converted wide string
+    ///
+    /// \see toAnsiString, operator std::wstring
+    ///
+    ////////////////////////////////////////////////////////////
+    std::wstring toWideString() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert the Unicode string to a UTF-8 string
+    ///
+    /// \return Converted UTF-8 string
+    ///
+    /// \see toUtf16, toUtf32
+    ///
+    ////////////////////////////////////////////////////////////
+    std::basic_string<Uint8> toUtf8() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert the Unicode string to a UTF-16 string
+    ///
+    /// \return Converted UTF-16 string
+    ///
+    /// \see toUtf8, toUtf32
+    ///
+    ////////////////////////////////////////////////////////////
+    std::basic_string<Uint16> toUtf16() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert the Unicode string to a UTF-32 string
+    ///
+    /// This function doesn't perform any conversion, since the
+    /// string is already stored as UTF-32 internally.
+    ///
+    /// \return Converted UTF-32 string
+    ///
+    /// \see toUtf8, toUtf16
+    ///
+    ////////////////////////////////////////////////////////////
+    std::basic_string<Uint32> toUtf32() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of assignment operator
+    ///
+    /// \param right Instance to assign
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    String& operator =(const String& right);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of += operator to append an UTF-32 string
+    ///
+    /// \param right String to append
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    String& operator +=(const String& right);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of [] operator to access a character by its position
+    ///
+    /// This function provides read-only access to characters.
+    /// Note: the behavior is undefined if \a index is out of range.
+    ///
+    /// \param index Index of the character to get
+    ///
+    /// \return Character at position \a index
+    ///
+    ////////////////////////////////////////////////////////////
+    Uint32 operator [](std::size_t index) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of [] operator to access a character by its position
+    ///
+    /// This function provides read and write access to characters.
+    /// Note: the behavior is undefined if \a index is out of range.
+    ///
+    /// \param index Index of the character to get
+    ///
+    /// \return Reference to the character at position \a index
+    ///
+    ////////////////////////////////////////////////////////////
+    Uint32& operator [](std::size_t index);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Clear the string
+    ///
+    /// This function removes all the characters from the string.
+    ///
+    /// \see isEmpty, erase
+    ///
+    ////////////////////////////////////////////////////////////
+    void clear();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the size of the string
+    ///
+    /// \return Number of characters in the string
+    ///
+    /// \see isEmpty
+    ///
+    ////////////////////////////////////////////////////////////
+    std::size_t getSize() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check whether the string is empty or not
+    ///
+    /// \return True if the string is empty (i.e. contains no character)
+    ///
+    /// \see clear, getSize
+    ///
+    ////////////////////////////////////////////////////////////
+    bool isEmpty() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Erase one or more characters from the string
+    ///
+    /// This function removes a sequence of \a count characters
+    /// starting from \a position.
+    ///
+    /// \param position Position of the first character to erase
+    /// \param count    Number of characters to erase
+    ///
+    ////////////////////////////////////////////////////////////
+    void erase(std::size_t position, std::size_t count = 1);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Insert one or more characters into the string
+    ///
+    /// This function inserts the characters of \a str
+    /// into the string, starting from \a position.
+    ///
+    /// \param position Position of insertion
+    /// \param str      Characters to insert
+    ///
+    ////////////////////////////////////////////////////////////
+    void insert(std::size_t position, const String& str);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Find a sequence of one or more characters in the string
+    ///
+    /// This function searches for the characters of \a str
+    /// in the string, starting from \a start.
+    ///
+    /// \param str   Characters to find
+    /// \param start Where to begin searching
+    ///
+    /// \return Position of \a str in the string, or String::InvalidPos if not found
+    ///
+    ////////////////////////////////////////////////////////////
+    std::size_t find(const String& str, std::size_t start = 0) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Replace a substring with another string
+    ///
+    /// This function replaces the substring that starts at index \a position
+    /// and spans \a length characters with the string \a replaceWith.
+    ///
+    /// \param position    Index of the first character to be replaced
+    /// \param length      Number of characters to replace. You can pass InvalidPos to
+    ///                    replace all characters until the end of the string.
+    /// \param replaceWith String that replaces the given substring.
+    ///
+    ////////////////////////////////////////////////////////////
+    void replace(std::size_t position, std::size_t length, const String& replaceWith);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Replace all occurrences of a substring with a replacement string
+    ///
+    /// This function replaces all occurrences of \a searchFor in this string
+    /// with the string \a replaceWith.
+    ///
+    /// \param searchFor   The value being searched for
+    /// \param replaceWith The value that replaces found \a searchFor values
+    ///
+    ////////////////////////////////////////////////////////////
+    void replace(const String& searchFor, const String& replaceWith);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return a part of the string
+    ///
+    /// This function returns the substring that starts at index \a position
+    /// and spans \a length characters.
+    ///
+    /// \param position Index of the first character
+    /// \param length   Number of characters to include in the substring (if
+    ///                 the string is shorter, as many characters as possible
+    ///                 are included). \ref InvalidPos can be used to include all
+    ///                 characters until the end of the string.
+    ///
+    /// \return String object containing a substring of this object
+    ///
+    ////////////////////////////////////////////////////////////
+    String substring(std::size_t position, std::size_t length = InvalidPos) const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get a pointer to the C-style array of characters
+    ///
+    /// This functions provides a read-only access to a
+    /// null-terminated C-style representation of the string.
+    /// The returned pointer is temporary and is meant only for
+    /// immediate use, thus it is not recommended to store it.
+    ///
+    /// \return Read-only pointer to the array of characters
+    ///
+    ////////////////////////////////////////////////////////////
+    const Uint32* getData() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return an iterator to the beginning of the string
+    ///
+    /// \return Read-write iterator to the beginning of the string characters
+    ///
+    /// \see end
+    ///
+    ////////////////////////////////////////////////////////////
+    Iterator begin();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return an iterator to the beginning of the string
+    ///
+    /// \return Read-only iterator to the beginning of the string characters
+    ///
+    /// \see end
+    ///
+    ////////////////////////////////////////////////////////////
+    ConstIterator begin() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return an iterator to the end of the string
+    ///
+    /// The end iterator refers to 1 position past the last character;
+    /// thus it represents an invalid character and should never be
+    /// accessed.
+    ///
+    /// \return Read-write iterator to the end of the string characters
+    ///
+    /// \see begin
+    ///
+    ////////////////////////////////////////////////////////////
+    Iterator end();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return an iterator to the end of the string
+    ///
+    /// The end iterator refers to 1 position past the last character;
+    /// thus it represents an invalid character and should never be
+    /// accessed.
+    ///
+    /// \return Read-only iterator to the end of the string characters
+    ///
+    /// \see begin
+    ///
+    ////////////////////////////////////////////////////////////
+    ConstIterator end() const;
+
+private:
+
+    friend SFML_SYSTEM_API bool operator ==(const String& left, const String& right);
+    friend SFML_SYSTEM_API bool operator <(const String& left, const String& right);
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    std::basic_string<Uint32> m_string; ///< Internal string of UTF-32 characters
+};
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of == operator to compare two UTF-32 strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return True if both strings are equal
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator ==(const String& left, const String& right);
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of != operator to compare two UTF-32 strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return True if both strings are different
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator !=(const String& left, const String& right);
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of < operator to compare two UTF-32 strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return True if \a left is lexicographically before \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator <(const String& left, const String& right);
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of > operator to compare two UTF-32 strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return True if \a left is lexicographically after \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator >(const String& left, const String& right);
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of <= operator to compare two UTF-32 strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return True if \a left is lexicographically before or equivalent to \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator <=(const String& left, const String& right);
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of >= operator to compare two UTF-32 strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return True if \a left is lexicographically after or equivalent to \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator >=(const String& left, const String& right);
+
+////////////////////////////////////////////////////////////
+/// \relates String
+/// \brief Overload of binary + operator to concatenate two strings
+///
+/// \param left  Left operand (a string)
+/// \param right Right operand (a string)
+///
+/// \return Concatenated string
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API String operator +(const String& left, const String& right);
+
+#include <SFML/System/String.inl>
+
+} // namespace sf
+
+
+#endif // SFML_STRING_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::String
+/// \ingroup system
+///
+/// sf::String is a utility string class defined mainly for
+/// convenience. It is a Unicode string (implemented using
+/// UTF-32), thus it can store any character in the world
+/// (European, Chinese, Arabic, Hebrew, etc.).
+///
+/// It automatically handles conversions from/to ANSI and
+/// wide strings, so that you can work with standard string
+/// classes and still be compatible with functions taking a
+/// sf::String.
+///
+/// \code
+/// sf::String s;
+///
+/// std::string s1 = s;  // automatically converted to ANSI string
+/// std::wstring s2 = s; // automatically converted to wide string
+/// s = "hello";         // automatically converted from ANSI string
+/// s = L"hello";        // automatically converted from wide string
+/// s += 'a';            // automatically converted from ANSI string
+/// s += L'a';           // automatically converted from wide string
+/// \endcode
+///
+/// Conversions involving ANSI strings use the default user locale. However
+/// it is possible to use a custom locale if necessary:
+/// \code
+/// std::locale locale;
+/// sf::String s;
+/// ...
+/// std::string s1 = s.toAnsiString(locale);
+/// s = sf::String("hello", locale);
+/// \endcode
+///
+/// sf::String defines the most important functions of the
+/// standard std::string class: removing, random access, iterating,
+/// appending, comparing, etc. However it is a simple class
+/// provided for convenience, and you may have to consider using
+/// a more optimized class if your program requires complex string
+/// handling. The automatic conversion functions will then take
+/// care of converting your string to sf::String whenever SFML
+/// requires it.
+///
+/// Please note that SFML also defines a low-level, generic
+/// interface for Unicode handling, see the sf::Utf classes.
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/String.inl b/dependencies64/sfml/include/SFML/System/String.inl
new file mode 100644 (file)
index 0000000..9f8f1b4
--- /dev/null
@@ -0,0 +1,53 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf8(T begin, T end)
+{
+    String string;
+    Utf8::toUtf32(begin, end, std::back_inserter(string.m_string));
+    return string;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf16(T begin, T end)
+{
+    String string;
+    Utf16::toUtf32(begin, end, std::back_inserter(string.m_string));
+    return string;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename T>
+String String::fromUtf32(T begin, T end)
+{
+    String string;
+    string.m_string.assign(begin, end);
+    return string;
+}
index f1d5b8d73a1a38ec94a4c59e4558ab7dbc768952..63bb1a44ab83b2a32701984e21cb3874640057d8 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/System/Export.hpp>
+#include <SFML/System/NonCopyable.hpp>
+#include <cstdlib>
 
 
-#ifdef SFML_SYSTEM_WINDOWS
+namespace sf
+{
+namespace priv
+{
+    class ThreadImpl;
+    struct ThreadFunc;
+}
 
-    #include <SFML/System/Win32/Thread.hpp>
+////////////////////////////////////////////////////////////
+/// \brief Utility class to manipulate threads
+///
+////////////////////////////////////////////////////////////
+class SFML_SYSTEM_API Thread : NonCopyable
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the thread from a functor with no argument
+    ///
+    /// This constructor works for function objects, as well
+    /// as free functions.
+    ///
+    /// Use this constructor for this kind of function:
+    /// \code
+    /// void function();
+    ///
+    /// // --- or ----
+    ///
+    /// struct Functor
+    /// {
+    ///     void operator()();
+    /// };
+    /// \endcode
+    /// Note: this does *not* run the thread, use launch().
+    ///
+    /// \param function Functor or free function to use as the entry point of the thread
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename F>
+    Thread(F function);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the thread from a functor with an argument
+    ///
+    /// This constructor works for function objects, as well
+    /// as free functions.
+    /// It is a template, which means that the argument can
+    /// have any type (int, std::string, void*, Toto, ...).
+    ///
+    /// Use this constructor for this kind of function:
+    /// \code
+    /// void function(int arg);
+    ///
+    /// // --- or ----
+    ///
+    /// struct Functor
+    /// {
+    ///     void operator()(std::string arg);
+    /// };
+    /// \endcode
+    /// Note: this does *not* run the thread, use launch().
+    ///
+    /// \param function Functor or free function to use as the entry point of the thread
+    /// \param argument argument to forward to the function
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename F, typename A>
+    Thread(F function, A argument);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the thread from a member function and an object
+    ///
+    /// This constructor is a template, which means that you can
+    /// use it with any class.
+    /// Use this constructor for this kind of function:
+    /// \code
+    /// class MyClass
+    /// {
+    /// public:
+    ///
+    ///     void function();
+    /// };
+    /// \endcode
+    /// Note: this does *not* run the thread, use launch().
+    ///
+    /// \param function Entry point of the thread
+    /// \param object Pointer to the object to use
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename C>
+    Thread(void(C::*function)(), C* object);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Destructor
+    ///
+    /// This destructor calls wait(), so that the internal thread
+    /// cannot survive after its sf::Thread instance is destroyed.
+    ///
+    ////////////////////////////////////////////////////////////
+    ~Thread();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Run the thread
+    ///
+    /// This function starts the entry point passed to the
+    /// thread's constructor, and returns immediately.
+    /// After this function returns, the thread's function is
+    /// running in parallel to the calling code.
+    ///
+    ////////////////////////////////////////////////////////////
+    void launch();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Wait until the thread finishes
+    ///
+    /// This function will block the execution until the
+    /// thread's function ends.
+    /// Warning: if the thread function never ends, the calling
+    /// thread will block forever.
+    /// If this function is called from its owner thread, it
+    /// returns without doing anything.
+    ///
+    ////////////////////////////////////////////////////////////
+    void wait();
 
-#else
+    ////////////////////////////////////////////////////////////
+    /// \brief Terminate the thread
+    ///
+    /// This function immediately stops the thread, without waiting
+    /// for its function to finish.
+    /// Terminating a thread with this function is not safe,
+    /// and can lead to local variables not being destroyed
+    /// on some operating systems. You should rather try to make
+    /// the thread function terminate by itself.
+    ///
+    ////////////////////////////////////////////////////////////
+    void terminate();
 
-    #include <SFML/System/Unix/Thread.hpp>
+private:
 
-#endif
+    friend class priv::ThreadImpl;
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Internal entry point of the thread
+    ///
+    /// This function is called by the thread implementation.
+    ///
+    ////////////////////////////////////////////////////////////
+    void run();
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    priv::ThreadImpl* m_impl;       ///< OS-specific implementation of the thread
+    priv::ThreadFunc* m_entryPoint; ///< Abstraction of the function to run
+};
+
+#include <SFML/System/Thread.inl>
+
+} // namespace sf
 
 #endif // SFML_THREAD_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Thread
+/// \ingroup system
+///
+/// Threads provide a way to run multiple parts of the code
+/// in parallel. When you launch a new thread, the execution
+/// is split and both the new thread and the caller run
+/// in parallel.
+///
+/// To use a sf::Thread, you construct it directly with the
+/// function to execute as the entry point of the thread.
+/// sf::Thread has multiple template constructors, which means
+/// that you can use several types of entry points:
+/// \li non-member functions with no argument
+/// \li non-member functions with one argument of any type
+/// \li functors with no argument (this one is particularly useful for compatibility with boost/std::%bind)
+/// \li functors with one argument of any type
+/// \li member functions from any class with no argument
+///
+/// The function argument, if any, is copied in the sf::Thread
+/// instance, as well as the functor (if the corresponding
+/// constructor is used). Class instances, however, are passed
+/// by pointer so you must make sure that the object won't be
+/// destroyed while the thread is still using it.
+///
+/// The thread ends when its function is terminated. If the
+/// owner sf::Thread instance is destroyed before the
+/// thread is finished, the destructor will wait (see wait())
+///
+/// Usage examples:
+/// \code
+/// // example 1: non member function with one argument
+///
+/// void threadFunc(int argument)
+/// {
+///     ...
+/// }
+///
+/// sf::Thread thread(&threadFunc, 5);
+/// thread.launch(); // start the thread (internally calls threadFunc(5))
+/// \endcode
+///
+/// \code
+/// // example 2: member function
+///
+/// class Task
+/// {
+/// public:
+///     void run()
+///     {
+///         ...
+///     }
+/// };
+///
+/// Task task;
+/// sf::Thread thread(&Task::run, &task);
+/// thread.launch(); // start the thread (internally calls task.run())
+/// \endcode
+///
+/// \code
+/// // example 3: functor
+///
+/// struct Task
+/// {
+///     void operator()()
+///     {
+///         ...
+///     }
+/// };
+///
+/// sf::Thread thread(Task());
+/// thread.launch(); // start the thread (internally calls operator() on the Task instance)
+/// \endcode
+///
+/// Creating parallel threads of execution can be dangerous:
+/// all threads inside the same process share the same memory space,
+/// which means that you may end up accessing the same variable
+/// from multiple threads at the same time. To prevent this
+/// kind of situations, you can use mutexes (see sf::Mutex).
+///
+/// \see sf::Mutex
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/Thread.inl b/dependencies64/sfml/include/SFML/System/Thread.inl
new file mode 100644 (file)
index 0000000..9df4d2c
--- /dev/null
@@ -0,0 +1,90 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+namespace priv
+{
+// Base class for abstract thread functions
+struct ThreadFunc
+{
+    virtual ~ThreadFunc() {}
+    virtual void run() = 0;
+};
+
+// Specialization using a functor (including free functions) with no argument
+template <typename T>
+struct ThreadFunctor : ThreadFunc
+{
+    ThreadFunctor(T functor) : m_functor(functor) {}
+    virtual void run() {m_functor();}
+    T m_functor;
+};
+
+// Specialization using a functor (including free functions) with one argument
+template <typename F, typename A>
+struct ThreadFunctorWithArg : ThreadFunc
+{
+    ThreadFunctorWithArg(F function, A arg) : m_function(function), m_arg(arg) {}
+    virtual void run() {m_function(m_arg);}
+    F m_function;
+    A m_arg;
+};
+
+// Specialization using a member function
+template <typename C>
+struct ThreadMemberFunc : ThreadFunc
+{
+    ThreadMemberFunc(void(C::*function)(), C* object) : m_function(function), m_object(object) {}
+    virtual void run() {(m_object->*m_function)();}
+    void(C::*m_function)();
+    C* m_object;
+};
+
+} // namespace priv
+
+
+////////////////////////////////////////////////////////////
+template <typename F>
+Thread::Thread(F functor) :
+m_impl      (NULL),
+m_entryPoint(new priv::ThreadFunctor<F>(functor))
+{
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename F, typename A>
+Thread::Thread(F function, A argument) :
+m_impl      (NULL),
+m_entryPoint(new priv::ThreadFunctorWithArg<F, A>(function, argument))
+{
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename C>
+Thread::Thread(void(C::*function)(), C* object) :
+m_impl      (NULL),
+m_entryPoint(new priv::ThreadMemberFunc<C>(function, object))
+{
+}
similarity index 61%
rename from dependencies64/sfml/include/SFML/System/Win32/Mutex.hpp
rename to dependencies64/sfml/include/SFML/System/ThreadLocal.hpp
index f833bc27ba3d299601c09734922c29750cdcf455..00703a73347b96533ad3f4dbad92a62c891b1649 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 //
 ////////////////////////////////////////////////////////////
 
-#ifndef SFML_MUTEXWIN32_HPP
-#define SFML_MUTEXWIN32_HPP
+#ifndef SFML_THREADLOCAL_HPP
+#define SFML_THREADLOCAL_HPP
 
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
+#include <SFML/System/Export.hpp>
 #include <SFML/System/NonCopyable.hpp>
-#include <windows.h>
+#include <cstdlib>
 
 
 namespace sf
 {
+namespace priv
+{
+    class ThreadLocalImpl;
+}
+
 ////////////////////////////////////////////////////////////
-/// Mutex defines a mutex (MUTual EXclusion) object,
-/// that allows a thread to lock critical instructions
-/// to avoid simultaneous access with other threads.
-/// The Win32 version uses critical sections, as it is
-/// faster than mutexes.<br/>
-/// See Lock for an efficient way of using it.
+/// \brief Defines variables with thread-local storage
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Mutex : NonCopyable
+class SFML_SYSTEM_API ThreadLocal : NonCopyable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// \param value Optional value to initialize the variable
     ///
     ////////////////////////////////////////////////////////////
-    Mutex();
+    ThreadLocal(void* value = NULL);
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
-    ~Mutex();
+    ~ThreadLocal();
 
     ////////////////////////////////////////////////////////////
-    /// Lock the mutex
+    /// \brief Set the thread-specific value of the variable
+    ///
+    /// \param value Value of the variable for the current thread
     ///
     ////////////////////////////////////////////////////////////
-    void Lock();
+    void setValue(void* value);
 
     ////////////////////////////////////////////////////////////
-    /// Unlock the mutex
+    /// \brief Retrieve the thread-specific value of the variable
+    ///
+    /// \return Value of the variable for the current thread
     ///
     ////////////////////////////////////////////////////////////
-    void Unlock();
+    void* getValue() const;
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    CRITICAL_SECTION myHandle; ///< Win32 handle of the mutex
+    priv::ThreadLocalImpl* m_impl; ///< Pointer to the OS specific implementation
 };
 
 } // namespace sf
 
 
-#endif // SFML_MUTEXWIN32_HPP
+#endif // SFML_THREADLOCAL_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::ThreadLocal
+/// \ingroup system
+///
+/// This class manipulates void* parameters and thus is not
+/// appropriate for strongly-typed variables. You should rather
+/// use the sf::ThreadLocalPtr template class.
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/ThreadLocalPtr.hpp b/dependencies64/sfml/include/SFML/System/ThreadLocalPtr.hpp
new file mode 100644 (file)
index 0000000..e703dac
--- /dev/null
@@ -0,0 +1,158 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_THREADLOCALPTR_HPP
+#define SFML_THREADLOCALPTR_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/ThreadLocal.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Pointer to a thread-local variable
+///
+////////////////////////////////////////////////////////////
+template <typename T>
+class ThreadLocalPtr : private ThreadLocal
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// \param value Optional value to initialize the variable
+    ///
+    ////////////////////////////////////////////////////////////
+    ThreadLocalPtr(T* value = NULL);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of unary operator *
+    ///
+    /// Like raw pointers, applying the * operator returns a
+    /// reference to the pointed-to object.
+    ///
+    /// \return Reference to the thread-local variable
+    ///
+    ////////////////////////////////////////////////////////////
+    T& operator *() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Overload of operator ->
+    ///
+    /// Similarly to raw pointers, applying the -> operator
+    /// returns the pointed-to object.
+    ///
+    /// \return Pointer to the thread-local variable
+    ///
+    ////////////////////////////////////////////////////////////
+    T* operator ->() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Conversion operator to implicitly convert the
+    ///        pointer to its raw pointer type (T*)
+    ///
+    /// \return Pointer to the actual object
+    ///
+    ////////////////////////////////////////////////////////////
+    operator T*() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Assignment operator for a raw pointer parameter
+    ///
+    /// \param value Pointer to assign
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    ThreadLocalPtr<T>& operator =(T* value);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Assignment operator for a ThreadLocalPtr parameter
+    ///
+    /// \param right ThreadLocalPtr to assign
+    ///
+    /// \return Reference to self
+    ///
+    ////////////////////////////////////////////////////////////
+    ThreadLocalPtr<T>& operator =(const ThreadLocalPtr<T>& right);
+};
+
+} // namespace sf
+
+#include <SFML/System/ThreadLocalPtr.inl>
+
+
+#endif // SFML_THREADLOCALPTR_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::ThreadLocalPtr
+/// \ingroup system
+///
+/// sf::ThreadLocalPtr is a type-safe wrapper for storing
+/// pointers to thread-local variables. A thread-local
+/// variable holds a different value for each different
+/// thread, unlike normal variables that are shared.
+///
+/// Its usage is completely transparent, so that it is similar
+/// to manipulating the raw pointer directly (like any smart pointer).
+///
+/// Usage example:
+/// \code
+/// MyClass object1;
+/// MyClass object2;
+/// sf::ThreadLocalPtr<MyClass> objectPtr;
+///
+/// void thread1()
+/// {
+///     objectPtr = &object1; // doesn't impact thread2
+///     ...
+/// }
+///
+/// void thread2()
+/// {
+///     objectPtr = &object2; // doesn't impact thread1
+///     ...
+/// }
+///
+/// int main()
+/// {
+///     // Create and launch the two threads
+///     sf::Thread t1(&thread1);
+///     sf::Thread t2(&thread2);
+///     t1.launch();
+///     t2.launch();
+///
+///     return 0;
+/// }
+/// \endcode
+///
+/// ThreadLocalPtr is designed for internal use; however you
+/// can use it if you feel like it fits well your implementation.
+///
+////////////////////////////////////////////////////////////
similarity index 55%
rename from dependencies64/sfml/include/SFML/System/Resource.inl
rename to dependencies64/sfml/include/SFML/System/ThreadLocalPtr.inl
index 916586c3f40d9e6b16005b94cf4e139f6990a151..e378c621358751de2e4b8a25f0d8c4d66a91bfd2 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 
 
-////////////////////////////////////////////////////////////
-/// Default constructor
+namespace sf
+{
 ////////////////////////////////////////////////////////////
 template <typename T>
-Resource<T>::Resource()
+ThreadLocalPtr<T>::ThreadLocalPtr(T* value) :
+ThreadLocal(value)
 {
-    // Nothing to do
 }
 
 
-////////////////////////////////////////////////////////////
-/// Copy constructor
 ////////////////////////////////////////////////////////////
 template <typename T>
-Resource<T>::Resource(const Resource<T>&)
+T& ThreadLocalPtr<T>::operator *() const
 {
-    // Nothing to do, we don't want to copy observers
+    return *static_cast<T*>(getValue());
 }
 
 
-////////////////////////////////////////////////////////////
-/// Destructor
 ////////////////////////////////////////////////////////////
 template <typename T>
-Resource<T>::~Resource()
+T* ThreadLocalPtr<T>::operator ->() const
 {
-    // Notify all observers
-    for (typename std::set<ResourcePtr<T>*>::iterator i = myObservers.begin(); i != myObservers.end(); ++i)
-    {
-        (*i)->OnResourceDestroyed();
-    }
+    return static_cast<T*>(getValue());
 }
 
 
-////////////////////////////////////////////////////////////
-/// Assignment operator
 ////////////////////////////////////////////////////////////
 template <typename T>
-Resource<T>& Resource<T>::operator =(const Resource<T>&)
+ThreadLocalPtr<T>::operator T*() const
 {
-    // Nothing to do, we don't want to copy observers
-    return *this;
+    return static_cast<T*>(getValue());
 }
 
 
-////////////////////////////////////////////////////////////
-/// Connect a ResourcePtr to this resource
 ////////////////////////////////////////////////////////////
 template <typename T>
-void Resource<T>::Connect(ResourcePtr<T>& Observer) const
+ThreadLocalPtr<T>& ThreadLocalPtr<T>::operator =(T* value)
 {
-    myObservers.insert(&Observer);
+    setValue(value);
+    return *this;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Disconnect a ResourcePtr from this resource
 ////////////////////////////////////////////////////////////
 template <typename T>
-void Resource<T>::Disconnect(ResourcePtr<T>& Observer) const
+ThreadLocalPtr<T>& ThreadLocalPtr<T>::operator =(const ThreadLocalPtr<T>& right)
 {
-    myObservers.erase(&Observer);
+    setValue(right.getValue());
+    return *this;
 }
+
+} // namespace sf
diff --git a/dependencies64/sfml/include/SFML/System/Time.hpp b/dependencies64/sfml/include/SFML/System/Time.hpp
new file mode 100644 (file)
index 0000000..1268afc
--- /dev/null
@@ -0,0 +1,488 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TIME_HPP
+#define SFML_TIME_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/Export.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Represents a time value
+///
+////////////////////////////////////////////////////////////
+class SFML_SYSTEM_API Time
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// Sets the time value to zero.
+    ///
+    ////////////////////////////////////////////////////////////
+    Time();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the time value as a number of seconds
+    ///
+    /// \return Time in seconds
+    ///
+    /// \see asMilliseconds, asMicroseconds
+    ///
+    ////////////////////////////////////////////////////////////
+    float asSeconds() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the time value as a number of milliseconds
+    ///
+    /// \return Time in milliseconds
+    ///
+    /// \see asSeconds, asMicroseconds
+    ///
+    ////////////////////////////////////////////////////////////
+    Int32 asMilliseconds() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the time value as a number of microseconds
+    ///
+    /// \return Time in microseconds
+    ///
+    /// \see asSeconds, asMilliseconds
+    ///
+    ////////////////////////////////////////////////////////////
+    Int64 asMicroseconds() const;
+
+    ////////////////////////////////////////////////////////////
+    // Static member data
+    ////////////////////////////////////////////////////////////
+    static const Time Zero; ///< Predefined "zero" time value
+
+private:
+
+    friend SFML_SYSTEM_API Time seconds(float);
+    friend SFML_SYSTEM_API Time milliseconds(Int32);
+    friend SFML_SYSTEM_API Time microseconds(Int64);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct from a number of microseconds
+    ///
+    /// This function is internal. To construct time values,
+    /// use sf::seconds, sf::milliseconds or sf::microseconds instead.
+    ///
+    /// \param microseconds Number of microseconds
+    ///
+    ////////////////////////////////////////////////////////////
+    explicit Time(Int64 microseconds);
+
+private:
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    Int64 m_microseconds; ///< Time value stored as microseconds
+};
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Construct a time value from a number of seconds
+///
+/// \param amount Number of seconds
+///
+/// \return Time value constructed from the amount of seconds
+///
+/// \see milliseconds, microseconds
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time seconds(float amount);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Construct a time value from a number of milliseconds
+///
+/// \param amount Number of milliseconds
+///
+/// \return Time value constructed from the amount of milliseconds
+///
+/// \see seconds, microseconds
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time milliseconds(Int32 amount);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Construct a time value from a number of microseconds
+///
+/// \param amount Number of microseconds
+///
+/// \return Time value constructed from the amount of microseconds
+///
+/// \see seconds, milliseconds
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time microseconds(Int64 amount);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of == operator to compare two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return True if both time values are equal
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator ==(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of != operator to compare two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return True if both time values are different
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator !=(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of < operator to compare two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return True if \a left is lesser than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator <(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of > operator to compare two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return True if \a left is greater than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator >(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of <= operator to compare two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return True if \a left is lesser or equal than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator <=(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of >= operator to compare two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return True if \a left is greater or equal than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API bool operator >=(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of unary - operator to negate a time value
+///
+/// \param right Right operand (a time)
+///
+/// \return Opposite of the time value
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator -(Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary + operator to add two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return Sum of the two times values
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator +(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary += operator to add/assign two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return Sum of the two times values
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator +=(Time& left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary - operator to subtract two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return Difference of the two times values
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator -(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary -= operator to subtract/assign two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return Difference of the two times values
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator -=(Time& left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary * operator to scale a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left multiplied by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator *(Time left, float right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary * operator to scale a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left multiplied by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator *(Time left, Int64 right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary * operator to scale a time value
+///
+/// \param left  Left operand (a number)
+/// \param right Right operand (a time)
+///
+/// \return \a left multiplied by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator *(float left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary * operator to scale a time value
+///
+/// \param left  Left operand (a number)
+/// \param right Right operand (a time)
+///
+/// \return \a left multiplied by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator *(Int64 left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary *= operator to scale/assign a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left multiplied by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator *=(Time& left, float right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary *= operator to scale/assign a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left multiplied by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator *=(Time& left, Int64 right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary / operator to scale a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left divided by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator /(Time left, float right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary / operator to scale a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left divided by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator /(Time left, Int64 right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary /= operator to scale/assign a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left divided by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator /=(Time& left, float right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary /= operator to scale/assign a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a number)
+///
+/// \return \a left divided by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator /=(Time& left, Int64 right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary / operator to compute the ratio of two time values
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return \a left divided by \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API float operator /(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary % operator to compute remainder of a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return \a left modulo \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time operator %(Time left, Time right);
+
+////////////////////////////////////////////////////////////
+/// \relates Time
+/// \brief Overload of binary %= operator to compute/assign remainder of a time value
+///
+/// \param left  Left operand (a time)
+/// \param right Right operand (a time)
+///
+/// \return \a left modulo \a right
+///
+////////////////////////////////////////////////////////////
+SFML_SYSTEM_API Time& operator %=(Time& left, Time right);
+
+} // namespace sf
+
+
+#endif // SFML_TIME_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Time
+/// \ingroup system
+///
+/// sf::Time encapsulates a time value in a flexible way.
+/// It allows to define a time value either as a number of
+/// seconds, milliseconds or microseconds. It also works the
+/// other way round: you can read a time value as either
+/// a number of seconds, milliseconds or microseconds.
+///
+/// By using such a flexible interface, the API doesn't
+/// impose any fixed type or resolution for time values,
+/// and let the user choose its own favorite representation.
+///
+/// Time values support the usual mathematical operations:
+/// you can add or subtract two times, multiply or divide
+/// a time by a number, compare two times, etc.
+///
+/// Since they represent a time span and not an absolute time
+/// value, times can also be negative.
+///
+/// Usage example:
+/// \code
+/// sf::Time t1 = sf::seconds(0.1f);
+/// Int32 milli = t1.asMilliseconds(); // 100
+///
+/// sf::Time t2 = sf::milliseconds(30);
+/// Int64 micro = t2.asMicroseconds(); // 30000
+///
+/// sf::Time t3 = sf::microseconds(-800000);
+/// float sec = t3.asSeconds(); // -0.8
+/// \endcode
+///
+/// \code
+/// void update(sf::Time elapsed)
+/// {
+///    position += speed * elapsed.asSeconds();
+/// }
+///
+/// update(sf::milliseconds(100));
+/// \endcode
+///
+/// \see sf::Clock
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/Unicode.hpp b/dependencies64/sfml/include/SFML/System/Unicode.hpp
deleted file mode 100644 (file)
index e05c94c..0000000
+++ /dev/null
@@ -1,290 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_UNICODE_HPP
-#define SFML_UNICODE_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-#include <iterator>
-#include <locale>
-#include <string>
-#include <stdlib.h>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// Provides utility functions to convert from and to
-/// any unicode and ASCII encoding
-////////////////////////////////////////////////////////////
-class SFML_API Unicode
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Define a string type for each encoding
-    /// Warning : in UTF8 and UTF16 strings, one element doesn't
-    /// necessarily maps to one character ; only an UTF32 element
-    /// is wide enough to hold all possible unicode values
-    ////////////////////////////////////////////////////////////
-    typedef std::basic_string<Uint8>  UTF8String;
-    typedef std::basic_string<Uint16> UTF16String;
-    typedef std::basic_string<Uint32> UTF32String;
-
-    ////////////////////////////////////////////////////////////
-    /// This class is an abstract definition of a unicode text,
-    /// it can be converted from and to any kind of string
-    /// and encoding
-    ////////////////////////////////////////////////////////////
-    class SFML_API Text
-    {
-    public :
-
-        ////////////////////////////////////////////////////////////
-        /// Default constructor (empty text)
-        ///
-        ////////////////////////////////////////////////////////////
-        Text();
-
-        ////////////////////////////////////////////////////////////
-        /// Construct the unicode text from any type of string
-        ///
-        /// \param Str : String to convert
-        ///
-        ////////////////////////////////////////////////////////////
-        Text(const char*                 Str);
-        Text(const wchar_t*              Str);
-        Text(const Uint8*                Str);
-        Text(const Uint16*               Str);
-        Text(const Uint32*               Str);
-        Text(const std::string&          Str);
-        Text(const std::wstring&         Str);
-        Text(const Unicode::UTF8String&  Str);
-        Text(const Unicode::UTF16String& Str);
-        Text(const Unicode::UTF32String& Str);
-
-        ////////////////////////////////////////////////////////////
-        /// Operator to cast the text to any type of string
-        ///
-        /// \return Converted string
-        ///
-        ////////////////////////////////////////////////////////////
-        operator       std::string          () const;
-        operator       std::wstring         () const;
-        operator       Unicode::UTF8String  () const;
-        operator       Unicode::UTF16String () const;
-        operator const Unicode::UTF32String&() const;
-
-    private :
-
-        ////////////////////////////////////////////////////////////
-        // Data member
-        ////////////////////////////////////////////////////////////
-        sf::Unicode::UTF32String myUTF32String; ///< UTF-32 unicode text
-    };
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-32 characters range
-    /// to an ANSI characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    /// \param Locale :      Locale to use for conversion (uses the current one by default)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF32ToANSI(In Begin, In End, Out Output, char Replacement = '?', const std::locale& Locale = GetDefaultLocale());
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an ANSI characters range
-    /// to an UTF-32 characters range, using the given locale
-    ///
-    /// \param Begin :  Iterator pointing to the beginning of the input sequence
-    /// \param End :    Iterator pointing to the end of the input sequence
-    /// \param Output : Iterator pointing to the beginning of the output sequence
-    /// \param Locale : Locale to use for conversion (uses the current one by default)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out ANSIToUTF32(In Begin, In End, Out Output, const std::locale& Locale = GetDefaultLocale());
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-8 characters range
-    /// to an UTF-16 characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF8ToUTF16(In Begin, In End, Out Output, Uint16 Replacement = '?');
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-8 characters range
-    /// to an UTF-32 characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF8ToUTF32(In Begin, In End, Out Output, Uint32 Replacement = '?');
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-16 characters range
-    /// to an UTF-8 characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF16ToUTF8(In Begin, In End, Out Output, Uint8 Replacement = '?');
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-16 characters range
-    /// to an UTF-32 characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF16ToUTF32(In Begin, In End, Out Output, Uint32 Replacement = '?');
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-32 characters range
-    /// to an UTF-8 characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF32ToUTF8(In Begin, In End, Out Output, Uint8 Replacement = '?');
-
-    ////////////////////////////////////////////////////////////
-    /// Generic function to convert an UTF-32 characters range
-    /// to an UTF-16 characters range, using the given locale
-    ///
-    /// \param Begin :       Iterator pointing to the beginning of the input sequence
-    /// \param End :         Iterator pointing to the end of the input sequence
-    /// \param Output :      Iterator pointing to the beginning of the output sequence
-    /// \param Replacement : Replacement character for characters not convertible to output encoding ('?' by default -- use 0 to use no replacement character)
-    ///
-    /// \return Iterator to the end of the output sequence which has been written
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In, typename Out>
-    static Out UTF32ToUTF16(In Begin, In End, Out Output, Uint16 Replacement = '?');
-
-    ////////////////////////////////////////////////////////////
-    /// Get the number of characters composing an UTF-8 string
-    ///
-    /// \param Begin : Iterator pointing to the beginning of the input sequence
-    /// \param End :   Iterator pointing to the end of the input sequence
-    ///
-    /// \return Count of the characters in the string
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In>
-    static std::size_t GetUTF8Length(In Begin, In End);
-
-    ////////////////////////////////////////////////////////////
-    /// Get the number of characters composing an UTF-16 string
-    ///
-    /// \param Begin : Iterator pointing to the beginning of the input sequence
-    /// \param End :   Iterator pointing to the end of the input sequence
-    ///
-    /// \return Count of the characters in the string
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In>
-    static std::size_t GetUTF16Length(In Begin, In End);
-
-    ////////////////////////////////////////////////////////////
-    /// Get the number of characters composing an UTF-32 string
-    ///
-    /// \param Begin : Iterator pointing to the beginning of the input sequence
-    /// \param End :   Iterator pointing to the end of the input sequence
-    ///
-    /// \return Count of the characters in the string
-    ///
-    ////////////////////////////////////////////////////////////
-    template <typename In>
-    static std::size_t GetUTF32Length(In Begin, In End);
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    /// Get the default system locale
-    ///
-    /// \return Reference to the default system locale
-    ///
-    ////////////////////////////////////////////////////////////
-    static const std::locale& GetDefaultLocale();
-
-    ////////////////////////////////////////////////////////////
-    // Static member data
-    ////////////////////////////////////////////////////////////
-    static const int    UTF8TrailingBytes[256]; ///< Lookup table to find the length of an UTF-8 sequence
-    static const Uint32 UTF8Offsets[6];         ///< Magic values to subtract during UTF-8 conversions
-    static const Uint8  UTF8FirstBytes[7];      ///< First bytes for UTF-8 sequences
-};
-
-#include <SFML/System/Unicode.inl>
-
-} // namespace sf
-
-
-#endif // SFML_UNICODE_HPP
diff --git a/dependencies64/sfml/include/SFML/System/Unicode.inl b/dependencies64/sfml/include/SFML/System/Unicode.inl
deleted file mode 100644 (file)
index d7b6e2b..0000000
+++ /dev/null
@@ -1,474 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-32 characters range
-/// to an ANSI characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF32ToANSI(In Begin, In End, Out Output, char Replacement, const std::locale& Locale)
-{
-    #ifdef __MINGW32__
-
-        // MinGW has a almost no support for unicode stuff
-        // As a consequence, the MinGW version of this function can only use the default locale
-        // and ignores the one passed as parameter
-        while (Begin < End)
-        {
-            char Char = 0;
-            if (wctomb(&Char, static_cast<wchar_t>(*Begin++)) >= 0)
-                *Output++ = Char;
-            else if (Replacement)
-                *Output++ = Replacement;
-        }
-
-    #else
-
-        // Get the facet of the locale which deals with character conversion
-        const std::ctype<wchar_t>& Facet = std::use_facet< std::ctype<wchar_t> >(Locale);
-
-        // Use the facet to convert each character of the input string
-        while (Begin < End)
-            *Output++ = Facet.narrow(static_cast<wchar_t>(*Begin++), Replacement);
-
-    #endif
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an ANSI characters range
-/// to an UTF-32 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::ANSIToUTF32(In Begin, In End, Out Output, const std::locale& Locale)
-{
-    #ifdef __MINGW32__
-
-        // MinGW has a almost no support for unicode stuff
-        // As a consequence, the MinGW version of this function can only use the default locale
-        // and ignores the one passed as parameter
-        while (Begin < End)
-        {
-            wchar_t Char = 0;
-            mbtowc(&Char, &*Begin, 1);
-            Begin++;
-            *Output++ = static_cast<Uint32>(Char);
-        }
-
-    #else
-
-        // Get the facet of the locale which deals with character conversion
-        const std::ctype<wchar_t>& Facet = std::use_facet< std::ctype<wchar_t> >(Locale);
-
-        // Use the facet to convert each character of the input string
-        while (Begin < End)
-            *Output++ = static_cast<Uint32>(Facet.widen(*Begin++));
-
-    #endif
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-8 characters range
-/// to an UTF-16 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF8ToUTF16(In Begin, In End, Out Output, Uint16 Replacement)
-{
-    while (Begin < End)
-    {
-        Uint32 c = 0;
-        int TrailingBytes = UTF8TrailingBytes[static_cast<int>(*Begin)];
-        if (Begin + TrailingBytes < End)
-        {
-            // First decode the UTF-8 character
-            switch (TrailingBytes)
-            {
-                case 5 : c += *Begin++; c <<= 6;
-                case 4 : c += *Begin++; c <<= 6;
-                case 3 : c += *Begin++; c <<= 6;
-                case 2 : c += *Begin++; c <<= 6;
-                case 1 : c += *Begin++; c <<= 6;
-                case 0 : c += *Begin++;
-            }
-               c -= UTF8Offsets[TrailingBytes];
-
-            // Then encode it in UTF-16
-            if (c < 0xFFFF)
-            {
-                // Character can be converted directly to 16 bits, just need to check it's in the valid range
-                if ((c >= 0xD800) && (c <= 0xDFFF))
-                {
-                    // Invalid character (this range is reserved)
-                    if (Replacement)
-                        *Output++ = Replacement;
-                }
-                else
-                {
-                    // Valid character directly convertible to 16 bits
-                    *Output++ = static_cast<Uint16>(c);
-                }
-            }
-            else if (c > 0x0010FFFF)
-            {
-                // Invalid character (greater than the maximum unicode value)
-                if (Replacement)
-                    *Output++ = Replacement;
-            }
-            else
-            {
-                // Character will be converted to 2 UTF-16 elements
-                c -= 0x0010000;
-                *Output++ = static_cast<Uint16>((c >> 10)     + 0xD800);
-                *Output++ = static_cast<Uint16>((c & 0x3FFUL) + 0xDC00);
-            }
-        }
-    }
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-8 characters range
-/// to an UTF-32 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF8ToUTF32(In Begin, In End, Out Output, Uint32 Replacement)
-{
-    while (Begin < End)
-    {
-        Uint32 c = 0;
-        int TrailingBytes = UTF8TrailingBytes[static_cast<int>(*Begin)];
-        if (Begin + TrailingBytes < End)
-        {
-            // First decode the UTF-8 character
-            switch (TrailingBytes)
-            {
-                case 5 : c += *Begin++; c <<= 6;
-                case 4 : c += *Begin++; c <<= 6;
-                case 3 : c += *Begin++; c <<= 6;
-                case 2 : c += *Begin++; c <<= 6;
-                case 1 : c += *Begin++; c <<= 6;
-                case 0 : c += *Begin++;
-            }
-               c -= UTF8Offsets[TrailingBytes];
-
-            // Then write it if valid
-            if ((c < 0xD800) || (c > 0xDFFF))
-            {
-                // Valid UTF-32 character
-                *Output++ = c;
-            }
-            else
-            {
-                // Invalid UTF-32 character
-                if (Replacement)
-                    *Output++ = Replacement;
-            }
-        }
-    }
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-16 characters range
-/// to an UTF-8 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF16ToUTF8(In Begin, In End, Out Output, Uint8 Replacement)
-{
-    while (Begin < End)
-    {
-        Uint32 c = *Begin++;
-
-        // If it's a surrogate pair, first convert to a single UTF-32 character
-        if ((c >= 0xD800) && (c <= 0xDBFF))
-        {
-            if (Begin < End)
-            {
-                // The second element is valid : convert the two elements to a UTF-32 character
-                Uint32 d = *Begin++;
-                if ((d >= 0xDC00) && (d <= 0xDFFF))
-                    c = static_cast<Uint32>(((c - 0xD800) << 10) + (d - 0xDC00) + 0x0010000);
-            }
-            else
-            {
-                // Invalid second element
-                if (Replacement)
-                    *Output++ = Replacement;
-            }
-        }
-
-        // Then convert to UTF-8
-        if (c > 0x0010FFFF)
-        {
-            // Invalid character (greater than the maximum unicode value)
-            if (Replacement)
-                *Output++ = Replacement;
-        }
-        else
-        {
-            // Valid character
-
-            // Get number of bytes to write
-            int BytesToWrite = 1;
-            if      (c <  0x80)       BytesToWrite = 1;
-            else if (c <  0x800)      BytesToWrite = 2;
-            else if (c <  0x10000)    BytesToWrite = 3;
-            else if (c <= 0x0010FFFF) BytesToWrite = 4;
-
-            // Extract bytes to write
-            Uint8 Bytes[4];
-            switch (BytesToWrite)
-            {
-                case 4 : Bytes[3] = static_cast<Uint8>((c | 0x80) & 0xBF); c >>= 6;
-                case 3 : Bytes[2] = static_cast<Uint8>((c | 0x80) & 0xBF); c >>= 6;
-                case 2 : Bytes[1] = static_cast<Uint8>((c | 0x80) & 0xBF); c >>= 6;
-                case 1 : Bytes[0] = static_cast<Uint8> (c | UTF8FirstBytes[BytesToWrite]);
-            }
-
-            // Add them to the output
-            const Uint8* CurByte = Bytes;
-            switch (BytesToWrite)
-            {
-                case 4 : *Output++ = *CurByte++;
-                case 3 : *Output++ = *CurByte++;
-                case 2 : *Output++ = *CurByte++;
-                case 1 : *Output++ = *CurByte++;
-            }
-        }
-    }
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-16 characters range
-/// to an UTF-32 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF16ToUTF32(In Begin, In End, Out Output, Uint32 Replacement)
-{
-    while (Begin < End)
-    {
-        Uint16 c = *Begin++;
-        if ((c >= 0xD800) && (c <= 0xDBFF))
-        {
-            // We have a surrogate pair, ie. a character composed of two elements
-            if (Begin < End)
-            {
-                Uint16 d = *Begin++;
-                if ((d >= 0xDC00) && (d <= 0xDFFF))
-                {
-                    // The second element is valid : convert the two elements to a UTF-32 character
-                    *Output++ = static_cast<Uint32>(((c - 0xD800) << 10) + (d - 0xDC00) + 0x0010000);
-                }
-                else
-                {
-                    // Invalid second element
-                    if (Replacement)
-                        *Output++ = Replacement;
-                }
-            }
-        }
-        else if ((c >= 0xDC00) && (c <= 0xDFFF))
-        {
-            // Invalid character
-            if (Replacement)
-                *Output++ = Replacement;
-        }
-        else
-        {
-            // Valid character directly convertible to UTF-32
-            *Output++ = static_cast<Uint32>(c);
-        }
-    }
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-32 characters range
-/// to an UTF-8 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF32ToUTF8(In Begin, In End, Out Output, Uint8 Replacement)
-{
-    while (Begin < End)
-    {
-        Uint32 c = *Begin++;
-        if (c > 0x0010FFFF)
-        {
-            // Invalid character (greater than the maximum unicode value)
-            if (Replacement)
-                *Output++ = Replacement;
-        }
-        else
-        {
-            // Valid character
-
-            // Get number of bytes to write
-            int BytesToWrite = 1;
-            if      (c <  0x80)       BytesToWrite = 1;
-            else if (c <  0x800)      BytesToWrite = 2;
-            else if (c <  0x10000)    BytesToWrite = 3;
-            else if (c <= 0x0010FFFF) BytesToWrite = 4;
-
-            // Extract bytes to write
-            Uint8 Bytes[4];
-            switch (BytesToWrite)
-            {
-                case 4 : Bytes[3] = static_cast<Uint8>((c | 0x80) & 0xBF); c >>= 6;
-                case 3 : Bytes[2] = static_cast<Uint8>((c | 0x80) & 0xBF); c >>= 6;
-                case 2 : Bytes[1] = static_cast<Uint8>((c | 0x80) & 0xBF); c >>= 6;
-                case 1 : Bytes[0] = static_cast<Uint8> (c | UTF8FirstBytes[BytesToWrite]);
-            }
-
-            // Add them to the output
-            const Uint8* CurByte = Bytes;
-            switch (BytesToWrite)
-            {
-                case 4 : *Output++ = *CurByte++;
-                case 3 : *Output++ = *CurByte++;
-                case 2 : *Output++ = *CurByte++;
-                case 1 : *Output++ = *CurByte++;
-            }
-        }
-    }
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Generic function to convert an UTF-32 characters range
-/// to an UTF-16 characters range, using the given locale
-////////////////////////////////////////////////////////////
-template <typename In, typename Out>
-inline Out Unicode::UTF32ToUTF16(In Begin, In End, Out Output, Uint16 Replacement)
-{
-    while (Begin < End)
-    {
-        Uint32 c = *Begin++;
-        if (c < 0xFFFF)
-        {
-            // Character can be converted directly to 16 bits, just need to check it's in the valid range
-            if ((c >= 0xD800) && (c <= 0xDFFF))
-            {
-                // Invalid character (this range is reserved)
-                if (Replacement)
-                    *Output++ = Replacement;
-            }
-            else
-            {
-                // Valid character directly convertible to 16 bits
-                *Output++ = static_cast<Uint16>(c);
-            }
-        }
-        else if (c > 0x0010FFFF)
-        {
-            // Invalid character (greater than the maximum unicode value)
-            if (Replacement)
-                *Output++ = Replacement;
-        }
-        else
-        {
-            // Character will be converted to 2 UTF-16 elements
-            c -= 0x0010000;
-            *Output++ = static_cast<Uint16>((c >> 10)     + 0xD800);
-            *Output++ = static_cast<Uint16>((c & 0x3FFUL) + 0xDC00);
-        }
-    }
-
-    return Output;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Get the number of characters composing an UTF-8 string
-////////////////////////////////////////////////////////////
-template <typename In>
-inline std::size_t Unicode::GetUTF8Length(In Begin, In End)
-{
-    std::size_t Length = 0;
-    while (Begin < End)
-    {
-        int NbBytes = UTF8TrailingBytes[static_cast<int>(*Begin)];
-        if (Begin + NbBytes < End)
-            ++Length;
-
-        Begin += NbBytes + 1;
-    }
-
-    return Length;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Get the number of characters composing an UTF-16 string
-////////////////////////////////////////////////////////////
-template <typename In>
-inline std::size_t Unicode::GetUTF16Length(In Begin, In End)
-{
-    std::size_t Length = 0;
-    while (Begin < End)
-    {
-        if ((*Begin >= 0xD800) && (*Begin <= 0xDBFF))
-        {
-            ++Begin;
-            if ((Begin < End) && ((*Begin >= 0xDC00) && (*Begin <= 0xDFFF)))
-            {
-                ++Length;
-            }
-        }
-        else
-        {
-            ++Length;
-        }
-
-        ++Begin;
-    }
-
-    return Length;
-}
-
-
-////////////////////////////////////////////////////////////
-/// Get the number of characters composing an UTF-32 string
-////////////////////////////////////////////////////////////
-template <typename In>
-inline std::size_t Unicode::GetUTF32Length(In Begin, In End)
-{
-    return End - Begin;
-}
diff --git a/dependencies64/sfml/include/SFML/System/Unix/Mutex.hpp b/dependencies64/sfml/include/SFML/System/Unix/Mutex.hpp
deleted file mode 100644 (file)
index 3fd01c6..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_MUTEXUNIX_HPP
-#define SFML_MUTEXUNIX_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/System/NonCopyable.hpp>
-#include <pthread.h>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// Mutex defines a mutex (MUTual EXclusion) object,
-/// that allows a thread to lock critical instructions
-/// to avoid simultaneous access with other threads.
-/// See Lock for an efficient way of using it.
-////////////////////////////////////////////////////////////
-class SFML_API Mutex : NonCopyable
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    Mutex();
-
-    ////////////////////////////////////////////////////////////
-    /// Destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    ~Mutex();
-
-    ////////////////////////////////////////////////////////////
-    /// Lock the mutex
-    ///
-    ////////////////////////////////////////////////////////////
-    void Lock();
-
-    ////////////////////////////////////////////////////////////
-    /// Unlock the mutex
-    ///
-    ////////////////////////////////////////////////////////////
-    void Unlock();
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    pthread_mutex_t myMutex; ///< pthread instance of the mutex
-};
-
-} // namespace sf
-
-
-#endif // SFML_MUTEXUNIX_HPP
diff --git a/dependencies64/sfml/include/SFML/System/Unix/Thread.hpp b/dependencies64/sfml/include/SFML/System/Unix/Thread.hpp
deleted file mode 100644 (file)
index e9af261..0000000
+++ /dev/null
@@ -1,124 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_THREADUNIX_HPP
-#define SFML_THREADUNIX_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/System/NonCopyable.hpp>
-#include <pthread.h>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// Thread defines a thread.
-/// There is two ways to use Thread :
-/// - Inherit from it and override the Run() virtual function
-/// - Construct a sfThread instance and pass it a function
-/// pointer to call
-////////////////////////////////////////////////////////////
-class SFML_API Thread : NonCopyable
-{
-public :
-
-    typedef void (*FuncType)(void*);
-
-    ////////////////////////////////////////////////////////////
-    /// Construct the thread from a function pointer
-    ///
-    /// \param Function : Entry point of the thread
-    /// \param UserData : Data to pass to the thread function (NULL by default)
-    ///
-    ////////////////////////////////////////////////////////////
-    Thread(FuncType Function, void* UserData = NULL);
-
-    ////////////////////////////////////////////////////////////
-    /// Virtual destructor
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual ~Thread();
-
-    ////////////////////////////////////////////////////////////
-    /// Create and run the thread
-    ///
-    ////////////////////////////////////////////////////////////
-    void Launch();
-
-    ////////////////////////////////////////////////////////////
-    /// Wait until the thread finishes
-    ///
-    ////////////////////////////////////////////////////////////
-    void Wait();
-
-    ////////////////////////////////////////////////////////////
-    /// Terminate the thread
-    /// Terminating a thread with this function is not safe,
-    /// you should rather try to make the thread function
-    /// terminate by itself
-    ///
-    ////////////////////////////////////////////////////////////
-    void Terminate();
-
-protected :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    Thread();
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    /// Function called as the thread entry point
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual void Run();
-
-    ////////////////////////////////////////////////////////////
-    /// Actual thread entry point, dispatches to instances
-    ///
-    /// \param UserData : Data to pass to the thread function
-    ///
-    /// \return Error code
-    ///
-    ////////////////////////////////////////////////////////////
-    static void* ThreadFunc(void* UserData);
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    pthread_t myThread;   ///< Unix thread instance
-    bool      myIsActive; ///< Thread state (active or inactive)
-    FuncType  myFunction; ///< Function to call as the thread entry point
-    void*     myUserData; ///< Data to pass to the thread function
-};
-
-} // namespace sf
-
-
-#endif // SFML_THREADUNIX_HPP
diff --git a/dependencies64/sfml/include/SFML/System/Utf.hpp b/dependencies64/sfml/include/SFML/System/Utf.hpp
new file mode 100644 (file)
index 0000000..8ffae99
--- /dev/null
@@ -0,0 +1,763 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_UTF_HPP
+#define SFML_UTF_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <algorithm>
+#include <locale>
+#include <string>
+#include <cstdlib>
+
+
+namespace sf
+{
+template <unsigned int N>
+class Utf;
+
+////////////////////////////////////////////////////////////
+/// \brief Specialization of the Utf template for UTF-8
+///
+////////////////////////////////////////////////////////////
+template <>
+class Utf<8>
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Decode a single UTF-8 character
+    ///
+    /// Decoding a character means finding its unique 32-bits
+    /// code (called the codepoint) in the Unicode standard.
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Codepoint of the decoded UTF-8 character
+    /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static In decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Encode a single UTF-8 character
+    ///
+    /// Encoding a character means converting a unique 32-bits
+    /// code (called the codepoint) in the target encoding, UTF-8.
+    ///
+    /// \param input       Codepoint to encode as UTF-8
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to UTF-8 (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename Out>
+    static Out encode(Uint32 input, Out output, Uint8 replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Advance to the next UTF-8 character
+    ///
+    /// This function is necessary for multi-elements encodings, as
+    /// a single character may use more than 1 storage element.
+    ///
+    /// \param begin Iterator pointing to the beginning of the input sequence
+    /// \param end   Iterator pointing to the end of the input sequence
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static In next(In begin, In end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Count the number of characters of a UTF-8 sequence
+    ///
+    /// This function is necessary for multi-elements encodings, as
+    /// a single character may use more than 1 storage element, thus the
+    /// total size can be different from (begin - end).
+    ///
+    /// \param begin Iterator pointing to the beginning of the input sequence
+    /// \param end   Iterator pointing to the end of the input sequence
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static std::size_t count(In begin, In end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an ANSI characters range to UTF-8
+    ///
+    /// The current global locale will be used by default, unless you
+    /// pass a custom one in the \a locale parameter.
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    /// \param locale Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a wide characters range to UTF-8
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromWide(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-8
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromLatin1(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-8 characters range to ANSI characters
+    ///
+    /// The current global locale will be used by default, unless you
+    /// pass a custom one in the \a locale parameter.
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+    /// \param locale      Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-8 characters range to wide characters
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-8 characters range to latin-1 (ISO-5589-1) characters
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toLatin1(In begin, In end, Out output, char replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-8 characters range to UTF-8
+    ///
+    /// This functions does nothing more than a direct copy;
+    /// it is defined only to provide the same interface as other
+    /// specializations of the sf::Utf<> template, and allow
+    /// generic code to be written on top of it.
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf8(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-8 characters range to UTF-16
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf16(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-8 characters range to UTF-32
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf32(In begin, In end, Out output);
+};
+
+////////////////////////////////////////////////////////////
+/// \brief Specialization of the Utf template for UTF-16
+///
+////////////////////////////////////////////////////////////
+template <>
+class Utf<16>
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Decode a single UTF-16 character
+    ///
+    /// Decoding a character means finding its unique 32-bits
+    /// code (called the codepoint) in the Unicode standard.
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Codepoint of the decoded UTF-16 character
+    /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static In decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Encode a single UTF-16 character
+    ///
+    /// Encoding a character means converting a unique 32-bits
+    /// code (called the codepoint) in the target encoding, UTF-16.
+    ///
+    /// \param input       Codepoint to encode as UTF-16
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to UTF-16 (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename Out>
+    static Out encode(Uint32 input, Out output, Uint16 replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Advance to the next UTF-16 character
+    ///
+    /// This function is necessary for multi-elements encodings, as
+    /// a single character may use more than 1 storage element.
+    ///
+    /// \param begin Iterator pointing to the beginning of the input sequence
+    /// \param end   Iterator pointing to the end of the input sequence
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static In next(In begin, In end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Count the number of characters of a UTF-16 sequence
+    ///
+    /// This function is necessary for multi-elements encodings, as
+    /// a single character may use more than 1 storage element, thus the
+    /// total size can be different from (begin - end).
+    ///
+    /// \param begin Iterator pointing to the beginning of the input sequence
+    /// \param end   Iterator pointing to the end of the input sequence
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static std::size_t count(In begin, In end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an ANSI characters range to UTF-16
+    ///
+    /// The current global locale will be used by default, unless you
+    /// pass a custom one in the \a locale parameter.
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    /// \param locale Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a wide characters range to UTF-16
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromWide(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-16
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromLatin1(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-16 characters range to ANSI characters
+    ///
+    /// The current global locale will be used by default, unless you
+    /// pass a custom one in the \a locale parameter.
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+    /// \param locale      Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-16 characters range to wide characters
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toLatin1(In begin, In end, Out output, char replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-16 characters range to UTF-8
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf8(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-16 characters range to UTF-16
+    ///
+    /// This functions does nothing more than a direct copy;
+    /// it is defined only to provide the same interface as other
+    /// specializations of the sf::Utf<> template, and allow
+    /// generic code to be written on top of it.
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf16(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-16 characters range to UTF-32
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf32(In begin, In end, Out output);
+};
+
+////////////////////////////////////////////////////////////
+/// \brief Specialization of the Utf template for UTF-32
+///
+////////////////////////////////////////////////////////////
+template <>
+class Utf<32>
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Decode a single UTF-32 character
+    ///
+    /// Decoding a character means finding its unique 32-bits
+    /// code (called the codepoint) in the Unicode standard.
+    /// For UTF-32, the character value is the same as the codepoint.
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Codepoint of the decoded UTF-32 character
+    /// \param replacement Replacement character to use in case the UTF-8 sequence is invalid
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static In decode(In begin, In end, Uint32& output, Uint32 replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Encode a single UTF-32 character
+    ///
+    /// Encoding a character means converting a unique 32-bits
+    /// code (called the codepoint) in the target encoding, UTF-32.
+    /// For UTF-32, the codepoint is the same as the character value.
+    ///
+    /// \param input       Codepoint to encode as UTF-32
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to UTF-32 (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename Out>
+    static Out encode(Uint32 input, Out output, Uint32 replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Advance to the next UTF-32 character
+    ///
+    /// This function is trivial for UTF-32, which can store
+    /// every character in a single storage element.
+    ///
+    /// \param begin Iterator pointing to the beginning of the input sequence
+    /// \param end   Iterator pointing to the end of the input sequence
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static In next(In begin, In end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Count the number of characters of a UTF-32 sequence
+    ///
+    /// This function is trivial for UTF-32, which can store
+    /// every character in a single storage element.
+    ///
+    /// \param begin Iterator pointing to the beginning of the input sequence
+    /// \param end   Iterator pointing to the end of the input sequence
+    ///
+    /// \return Iterator pointing to one past the last read element of the input sequence
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static std::size_t count(In begin, In end);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an ANSI characters range to UTF-32
+    ///
+    /// The current global locale will be used by default, unless you
+    /// pass a custom one in the \a locale parameter.
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    /// \param locale Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromAnsi(In begin, In end, Out output, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a wide characters range to UTF-32
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromWide(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a latin-1 (ISO-5589-1) characters range to UTF-32
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out fromLatin1(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-32 characters range to ANSI characters
+    ///
+    /// The current global locale will be used by default, unless you
+    /// pass a custom one in the \a locale parameter.
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to ANSI (use 0 to skip them)
+    /// \param locale      Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toAnsi(In begin, In end, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-32 characters range to wide characters
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toWide(In begin, In end, Out output, wchar_t replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert an UTF-16 characters range to latin-1 (ISO-5589-1) characters
+    ///
+    /// \param begin       Iterator pointing to the beginning of the input sequence
+    /// \param end         Iterator pointing to the end of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement for characters not convertible to wide (use 0 to skip them)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toLatin1(In begin, In end, Out output, char replacement = 0);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-32 characters range to UTF-8
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf8(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-32 characters range to UTF-16
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf16(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Convert a UTF-32 characters range to UTF-32
+    ///
+    /// This functions does nothing more than a direct copy;
+    /// it is defined only to provide the same interface as other
+    /// specializations of the sf::Utf<> template, and allow
+    /// generic code to be written on top of it.
+    ///
+    /// \param begin  Iterator pointing to the beginning of the input sequence
+    /// \param end    Iterator pointing to the end of the input sequence
+    /// \param output Iterator pointing to the beginning of the output sequence
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In, typename Out>
+    static Out toUtf32(In begin, In end, Out output);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Decode a single ANSI character to UTF-32
+    ///
+    /// This function does not exist in other specializations
+    /// of sf::Utf<>, it is defined for convenience (it is used by
+    /// several other conversion functions).
+    ///
+    /// \param input  Input ANSI character
+    /// \param locale Locale to use for conversion
+    ///
+    /// \return Converted character
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static Uint32 decodeAnsi(In input, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Decode a single wide character to UTF-32
+    ///
+    /// This function does not exist in other specializations
+    /// of sf::Utf<>, it is defined for convenience (it is used by
+    /// several other conversion functions).
+    ///
+    /// \param input Input wide character
+    ///
+    /// \return Converted character
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename In>
+    static Uint32 decodeWide(In input);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Encode a single UTF-32 character to ANSI
+    ///
+    /// This function does not exist in other specializations
+    /// of sf::Utf<>, it is defined for convenience (it is used by
+    /// several other conversion functions).
+    ///
+    /// \param codepoint   Iterator pointing to the beginning of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement if the input character is not convertible to ANSI (use 0 to skip it)
+    /// \param locale      Locale to use for conversion
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename Out>
+    static Out encodeAnsi(Uint32 codepoint, Out output, char replacement = 0, const std::locale& locale = std::locale());
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Encode a single UTF-32 character to wide
+    ///
+    /// This function does not exist in other specializations
+    /// of sf::Utf<>, it is defined for convenience (it is used by
+    /// several other conversion functions).
+    ///
+    /// \param codepoint   Iterator pointing to the beginning of the input sequence
+    /// \param output      Iterator pointing to the beginning of the output sequence
+    /// \param replacement Replacement if the input character is not convertible to wide (use 0 to skip it)
+    ///
+    /// \return Iterator to the end of the output sequence which has been written
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename Out>
+    static Out encodeWide(Uint32 codepoint, Out output, wchar_t replacement = 0);
+};
+
+#include <SFML/System/Utf.inl>
+
+// Make typedefs to get rid of the template syntax
+typedef Utf<8>  Utf8;
+typedef Utf<16> Utf16;
+typedef Utf<32> Utf32;
+
+} // namespace sf
+
+
+#endif // SFML_UTF_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Utf
+/// \ingroup system
+///
+/// Utility class providing generic functions for UTF conversions.
+///
+/// sf::Utf is a low-level, generic interface for counting, iterating,
+/// encoding and decoding Unicode characters and strings. It is able
+/// to handle ANSI, wide, latin-1, UTF-8, UTF-16 and UTF-32 encodings.
+///
+/// sf::Utf<X> functions are all static, these classes are not meant to
+/// be instantiated. All the functions are template, so that you
+/// can use any character / string type for a given encoding.
+///
+/// It has 3 specializations:
+/// \li sf::Utf<8> (typedef'd to sf::Utf8)
+/// \li sf::Utf<16> (typedef'd to sf::Utf16)
+/// \li sf::Utf<32> (typedef'd to sf::Utf32)
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/System/Utf.inl b/dependencies64/sfml/include/SFML/System/Utf.inl
new file mode 100644 (file)
index 0000000..8711ca0
--- /dev/null
@@ -0,0 +1,752 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+// References:
+//
+// http://www.unicode.org/
+// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.c
+// http://www.unicode.org/Public/PROGRAMS/CVTUTF/ConvertUTF.h
+// http://people.w3.org/rishida/scripts/uniview/conversion
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<8>::decode(In begin, In end, Uint32& output, Uint32 replacement)
+{
+    // Some useful precomputed data
+    static const int trailing[256] =
+    {
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+        1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+        2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5
+    };
+    static const Uint32 offsets[6] =
+    {
+        0x00000000, 0x00003080, 0x000E2080, 0x03C82080, 0xFA082080, 0x82082080
+    };
+
+    // decode the character
+    int trailingBytes = trailing[static_cast<Uint8>(*begin)];
+    if (begin + trailingBytes < end)
+    {
+        output = 0;
+        switch (trailingBytes)
+        {
+            case 5: output += static_cast<Uint8>(*begin++); output <<= 6;
+            case 4: output += static_cast<Uint8>(*begin++); output <<= 6;
+            case 3: output += static_cast<Uint8>(*begin++); output <<= 6;
+            case 2: output += static_cast<Uint8>(*begin++); output <<= 6;
+            case 1: output += static_cast<Uint8>(*begin++); output <<= 6;
+            case 0: output += static_cast<Uint8>(*begin++);
+        }
+        output -= offsets[trailingBytes];
+    }
+    else
+    {
+        // Incomplete character
+        begin = end;
+        output = replacement;
+    }
+
+    return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<8>::encode(Uint32 input, Out output, Uint8 replacement)
+{
+    // Some useful precomputed data
+    static const Uint8 firstBytes[7] =
+    {
+        0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC
+    };
+
+    // encode the character
+    if ((input > 0x0010FFFF) || ((input >= 0xD800) && (input <= 0xDBFF)))
+    {
+        // Invalid character
+        if (replacement)
+            *output++ = replacement;
+    }
+    else
+    {
+        // Valid character
+
+        // Get the number of bytes to write
+        std::size_t bytestoWrite = 1;
+        if      (input <  0x80)       bytestoWrite = 1;
+        else if (input <  0x800)      bytestoWrite = 2;
+        else if (input <  0x10000)    bytestoWrite = 3;
+        else if (input <= 0x0010FFFF) bytestoWrite = 4;
+
+        // Extract the bytes to write
+        Uint8 bytes[4];
+        switch (bytestoWrite)
+        {
+            case 4: bytes[3] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+            case 3: bytes[2] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+            case 2: bytes[1] = static_cast<Uint8>((input | 0x80) & 0xBF); input >>= 6;
+            case 1: bytes[0] = static_cast<Uint8> (input | firstBytes[bytestoWrite]);
+        }
+
+        // Add them to the output
+        output = std::copy(bytes, bytes + bytestoWrite, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<8>::next(In begin, In end)
+{
+    Uint32 codepoint;
+    return decode(begin, end, codepoint);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<8>::count(In begin, In end)
+{
+    std::size_t length = 0;
+    while (begin < end)
+    {
+        begin = next(begin, end);
+        ++length;
+    }
+
+    return length;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::fromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint = Utf<32>::decodeAnsi(*begin++, locale);
+        output = encode(codepoint, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::fromWide(In begin, In end, Out output)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint = Utf<32>::decodeWide(*begin++);
+        output = encode(codepoint, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::fromLatin1(In begin, In end, Out output)
+{
+    // Latin-1 is directly compatible with Unicode encodings,
+    // and can thus be treated as (a sub-range of) UTF-32
+    while (begin < end)
+        output = encode(*begin++, output);
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        output = Utf<32>::encodeAnsi(codepoint, output, replacement, locale);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::toWide(In begin, In end, Out output, wchar_t replacement)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        output = Utf<32>::encodeWide(codepoint, output, replacement);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::toLatin1(In begin, In end, Out output, char replacement)
+{
+    // Latin-1 is directly compatible with Unicode encodings,
+    // and can thus be treated as (a sub-range of) UTF-32
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        *output++ = codepoint < 256 ? static_cast<char>(codepoint) : replacement;
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::toUtf8(In begin, In end, Out output)
+{
+    return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::toUtf16(In begin, In end, Out output)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        output = Utf<16>::encode(codepoint, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<8>::toUtf32(In begin, In end, Out output)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        *output++ = codepoint;
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<16>::decode(In begin, In end, Uint32& output, Uint32 replacement)
+{
+    Uint16 first = *begin++;
+
+    // If it's a surrogate pair, first convert to a single UTF-32 character
+    if ((first >= 0xD800) && (first <= 0xDBFF))
+    {
+        if (begin < end)
+        {
+            Uint32 second = *begin++;
+            if ((second >= 0xDC00) && (second <= 0xDFFF))
+            {
+                // The second element is valid: convert the two elements to a UTF-32 character
+                output = static_cast<Uint32>(((first - 0xD800) << 10) + (second - 0xDC00) + 0x0010000);
+            }
+            else
+            {
+                // Invalid character
+                output = replacement;
+            }
+        }
+        else
+        {
+            // Invalid character
+            begin = end;
+            output = replacement;
+        }
+    }
+    else
+    {
+        // We can make a direct copy
+        output = first;
+    }
+
+    return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<16>::encode(Uint32 input, Out output, Uint16 replacement)
+{
+    if (input < 0xFFFF)
+    {
+        // The character can be copied directly, we just need to check if it's in the valid range
+        if ((input >= 0xD800) && (input <= 0xDFFF))
+        {
+            // Invalid character (this range is reserved)
+            if (replacement)
+                *output++ = replacement;
+        }
+        else
+        {
+            // Valid character directly convertible to a single UTF-16 character
+            *output++ = static_cast<Uint16>(input);
+        }
+    }
+    else if (input > 0x0010FFFF)
+    {
+        // Invalid character (greater than the maximum Unicode value)
+        if (replacement)
+            *output++ = replacement;
+    }
+    else
+    {
+        // The input character will be converted to two UTF-16 elements
+        input -= 0x0010000;
+        *output++ = static_cast<Uint16>((input >> 10)     + 0xD800);
+        *output++ = static_cast<Uint16>((input & 0x3FFUL) + 0xDC00);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<16>::next(In begin, In end)
+{
+    Uint32 codepoint;
+    return decode(begin, end, codepoint);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<16>::count(In begin, In end)
+{
+    std::size_t length = 0;
+    while (begin < end)
+    {
+        begin = next(begin, end);
+        ++length;
+    }
+
+    return length;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::fromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint = Utf<32>::decodeAnsi(*begin++, locale);
+        output = encode(codepoint, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::fromWide(In begin, In end, Out output)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint = Utf<32>::decodeWide(*begin++);
+        output = encode(codepoint, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::fromLatin1(In begin, In end, Out output)
+{
+    // Latin-1 is directly compatible with Unicode encodings,
+    // and can thus be treated as (a sub-range of) UTF-32
+    return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        output = Utf<32>::encodeAnsi(codepoint, output, replacement, locale);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::toWide(In begin, In end, Out output, wchar_t replacement)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        output = Utf<32>::encodeWide(codepoint, output, replacement);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::toLatin1(In begin, In end, Out output, char replacement)
+{
+    // Latin-1 is directly compatible with Unicode encodings,
+    // and can thus be treated as (a sub-range of) UTF-32
+    while (begin < end)
+    {
+        *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
+        begin++;
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::toUtf8(In begin, In end, Out output)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        output = Utf<8>::encode(codepoint, output);
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::toUtf16(In begin, In end, Out output)
+{
+    return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<16>::toUtf32(In begin, In end, Out output)
+{
+    while (begin < end)
+    {
+        Uint32 codepoint;
+        begin = decode(begin, end, codepoint);
+        *output++ = codepoint;
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<32>::decode(In begin, In /*end*/, Uint32& output, Uint32 /*replacement*/)
+{
+    output = *begin++;
+    return begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::encode(Uint32 input, Out output, Uint32 /*replacement*/)
+{
+    *output++ = input;
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+In Utf<32>::next(In begin, In /*end*/)
+{
+    return ++begin;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+std::size_t Utf<32>::count(In begin, In end)
+{
+    return begin - end;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::fromAnsi(In begin, In end, Out output, const std::locale& locale)
+{
+    while (begin < end)
+        *output++ = decodeAnsi(*begin++, locale);
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::fromWide(In begin, In end, Out output)
+{
+    while (begin < end)
+        *output++ = decodeWide(*begin++);
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::fromLatin1(In begin, In end, Out output)
+{
+    // Latin-1 is directly compatible with Unicode encodings,
+    // and can thus be treated as (a sub-range of) UTF-32
+    return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::toAnsi(In begin, In end, Out output, char replacement, const std::locale& locale)
+{
+    while (begin < end)
+        output = encodeAnsi(*begin++, output, replacement, locale);
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::toWide(In begin, In end, Out output, wchar_t replacement)
+{
+    while (begin < end)
+        output = encodeWide(*begin++, output, replacement);
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::toLatin1(In begin, In end, Out output, char replacement)
+{
+    // Latin-1 is directly compatible with Unicode encodings,
+    // and can thus be treated as (a sub-range of) UTF-32
+    while (begin < end)
+    {
+        *output++ = *begin < 256 ? static_cast<char>(*begin) : replacement;
+        begin++;
+    }
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::toUtf8(In begin, In end, Out output)
+{
+    while (begin < end)
+        output = Utf<8>::encode(*begin++, output);
+
+    return output;
+}
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::toUtf16(In begin, In end, Out output)
+{
+    while (begin < end)
+        output = Utf<16>::encode(*begin++, output);
+
+    return output;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In, typename Out>
+Out Utf<32>::toUtf32(In begin, In end, Out output)
+{
+    return std::copy(begin, end, output);
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+Uint32 Utf<32>::decodeAnsi(In input, const std::locale& locale)
+{
+    // On Windows, GCC's standard library (glibc++) has almost
+    // no support for Unicode stuff. As a consequence, in this
+    // context we can only use the default locale and ignore
+    // the one passed as parameter.
+
+    #if defined(SFML_SYSTEM_WINDOWS) &&                       /* if Windows ... */                          \
+       (defined(__GLIBCPP__) || defined (__GLIBCXX__)) &&     /* ... and standard library is glibc++ ... */ \
+      !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+
+        (void)locale; // to avoid warnings
+
+        wchar_t character = 0;
+        mbtowc(&character, &input, 1);
+        return static_cast<Uint32>(character);
+
+    #else
+
+        // Get the facet of the locale which deals with character conversion
+        const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
+
+        // Use the facet to convert each character of the input string
+        return static_cast<Uint32>(facet.widen(input));
+
+    #endif
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename In>
+Uint32 Utf<32>::decodeWide(In input)
+{
+    // The encoding of wide characters is not well defined and is left to the system;
+    // however we can safely assume that it is UCS-2 on Windows and
+    // UCS-4 on Unix systems.
+    // In both cases, a simple copy is enough (UCS-2 is a subset of UCS-4,
+    // and UCS-4 *is* UTF-32).
+
+    return input;
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::encodeAnsi(Uint32 codepoint, Out output, char replacement, const std::locale& locale)
+{
+    // On Windows, gcc's standard library (glibc++) has almost
+    // no support for Unicode stuff. As a consequence, in this
+    // context we can only use the default locale and ignore
+    // the one passed as parameter.
+
+    #if defined(SFML_SYSTEM_WINDOWS) &&                       /* if Windows ... */                          \
+       (defined(__GLIBCPP__) || defined (__GLIBCXX__)) &&     /* ... and standard library is glibc++ ... */ \
+      !(defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) /* ... and STLPort is not used on top of it */
+
+        (void)locale; // to avoid warnings
+
+        char character = 0;
+        if (wctomb(&character, static_cast<wchar_t>(codepoint)) >= 0)
+            *output++ = character;
+        else if (replacement)
+            *output++ = replacement;
+
+        return output;
+
+    #else
+
+        // Get the facet of the locale which deals with character conversion
+        const std::ctype<wchar_t>& facet = std::use_facet< std::ctype<wchar_t> >(locale);
+
+        // Use the facet to convert each character of the input string
+        *output++ = facet.narrow(static_cast<wchar_t>(codepoint), replacement);
+
+        return output;
+
+    #endif
+}
+
+
+////////////////////////////////////////////////////////////
+template <typename Out>
+Out Utf<32>::encodeWide(Uint32 codepoint, Out output, wchar_t replacement)
+{
+    // The encoding of wide characters is not well defined and is left to the system;
+    // however we can safely assume that it is UCS-2 on Windows and
+    // UCS-4 on Unix systems.
+    // For UCS-2 we need to check if the source characters fits in (UCS-2 is a subset of UCS-4).
+    // For UCS-4 we can do a direct copy (UCS-4 *is* UTF-32).
+
+    switch (sizeof(wchar_t))
+    {
+        case 4:
+        {
+            *output++ = static_cast<wchar_t>(codepoint);
+            break;
+        }
+
+        default:
+        {
+            if ((codepoint <= 0xFFFF) && ((codepoint < 0xD800) || (codepoint > 0xDFFF)))
+            {
+                *output++ = static_cast<wchar_t>(codepoint);
+            }
+            else if (replacement)
+            {
+                *output++ = replacement;
+            }
+            break;
+        }
+    }
+
+    return output;
+}
index f111d871c3bfae6a2c661c2eebcc72b8e6e69167..07b3e96f8425c9961f59a6506f35c9c1f817185b 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Vector2 is an utility class for manipulating 2 dimensional
-/// vectors. Template parameter defines the type of coordinates
-/// (integer, float, ...)
+/// \brief Utility template class for manipulating
+///        2-dimensional vectors
+///
 ////////////////////////////////////////////////////////////
 template <typename T>
 class Vector2
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// Creates a Vector2(0, 0).
     ///
     ////////////////////////////////////////////////////////////
     Vector2();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the vector from its coordinates
+    /// \brief Construct the vector from its coordinates
     ///
-    /// \param X X coordinate
-    /// \param Y Y coordinate
+    /// \param X X coordinate
+    /// \param Y Y coordinate
     ///
     ////////////////////////////////////////////////////////////
     Vector2(T X, T Y);
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vector from another type of vector
+    ///
+    /// This constructor doesn't replace the copy constructor,
+    /// it's called only when U != T.
+    /// A call to this constructor will fail to compile if U
+    /// is not convertible to T.
+    ///
+    /// \param vector Vector to convert
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename U>
+    explicit Vector2(const Vector2<U>& vector);
+
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
@@ -61,155 +77,225 @@ public :
 };
 
 ////////////////////////////////////////////////////////////
-/// Operator - overload ; returns the opposite of a vector
+/// \relates Vector2
+/// \brief Overload of unary operator -
 ///
-/// \param V : Vector to negate
+/// \param right Vector to negate
 ///
-/// \return -V
+/// \return Memberwise opposite of the vector
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator -(const Vector2<T>& V);
+Vector2<T> operator -(const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator += overload ; add two vectors and assign to the first op
+/// \relates Vector2
+/// \brief Overload of binary operator +=
+///
+/// This operator performs a memberwise addition of both vectors,
+/// and assigns the result to \a left.
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return V1 + V2
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator +=(Vector2<T>& V1, const Vector2<T>& V2);
+Vector2<T>& operator +=(Vector2<T>& left, const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator -= overload ; subtract two vectors and assign to the first op
+/// \relates Vector2
+/// \brief Overload of binary operator -=
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// This operator performs a memberwise subtraction of both vectors,
+/// and assigns the result to \a left.
 ///
-/// \return V1 - V2
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
+///
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator -=(Vector2<T>& V1, const Vector2<T>& V2);
+Vector2<T>& operator -=(Vector2<T>& left, const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator + overload ; adds two vectors
+/// \relates Vector2
+/// \brief Overload of binary operator +
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return V1 + V2
+/// \return Memberwise addition of both vectors
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator +(const Vector2<T>& V1, const Vector2<T>& V2);
+Vector2<T> operator +(const Vector2<T>& left, const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator - overload ; subtracts two vectors
+/// \relates Vector2
+/// \brief Overload of binary operator -
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return V1 - V2
+/// \return Memberwise subtraction of both vectors
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator -(const Vector2<T>& V1, const Vector2<T>& V2);
+Vector2<T> operator -(const Vector2<T>& left, const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a vector by a scalar value
+/// \relates Vector2
+/// \brief Overload of binary operator *
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
 ///
-/// \return V * X
+/// \return Memberwise multiplication by \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator *(const Vector2<T>& V, T X);
+Vector2<T> operator *(const Vector2<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a scalar value by a vector
+/// \relates Vector2
+/// \brief Overload of binary operator *
 ///
-/// \param X : Scalar value
-/// \param V : Vector
+/// \param left  Left operand (a scalar value)
+/// \param right Right operand (a vector)
 ///
-/// \return X * V
+/// \return Memberwise multiplication by \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator *(T X, const Vector2<T>& V);
+Vector2<T> operator *(T left, const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator *= overload ; multiply-assign a vector by a scalar value
+/// \relates Vector2
+/// \brief Overload of binary operator *=
+///
+/// This operator performs a memberwise multiplication by \a right,
+/// and assigns the result to \a left.
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
 ///
-/// \return V * X
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator *=(Vector2<T>& V, T X);
+Vector2<T>& operator *=(Vector2<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator / overload ; divide a vector by a scalar value
+/// \relates Vector2
+/// \brief Overload of binary operator /
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
 ///
-/// \return V / X
+/// \return Memberwise division by \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator /(const Vector2<T>& V, T X);
+Vector2<T> operator /(const Vector2<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator /= overload ; divide-assign a vector by a scalar value
+/// \relates Vector2
+/// \brief Overload of binary operator /=
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// This operator performs a memberwise division by \a right,
+/// and assigns the result to \a left.
 ///
-/// \return V / X
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
+///
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator /=(Vector2<T>& V, T X);
+Vector2<T>& operator /=(Vector2<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator == overload ; compares the equality of two vectors
+/// \relates Vector2
+/// \brief Overload of binary operator ==
+///
+/// This operator compares strict equality between two vectors.
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return True if V1 is equal to V2
+/// \return True if \a left is equal to \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator ==(const Vector2<T>& V1, const Vector2<T>& V2);
+bool operator ==(const Vector2<T>& left, const Vector2<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator != overload ; compares the difference of two vectors
+/// \relates Vector2
+/// \brief Overload of binary operator !=
+///
+/// This operator compares strict difference between two vectors.
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return True if V1 is different than V2
+/// \return True if \a left is not equal to \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator !=(const Vector2<T>& V1, const Vector2<T>& V2);
+bool operator !=(const Vector2<T>& left, const Vector2<T>& right);
 
 #include <SFML/System/Vector2.inl>
 
 // Define the most common types
-typedef Vector2<int>   Vector2i;
-typedef Vector2<float> Vector2f;
+typedef Vector2<int>          Vector2i;
+typedef Vector2<unsigned int> Vector2u;
+typedef Vector2<float>        Vector2f;
 
 } // namespace sf
 
 
 #endif // SFML_VECTOR2_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Vector2
+/// \ingroup system
+///
+/// sf::Vector2 is a simple class that defines a mathematical
+/// vector with two coordinates (x and y). It can be used to
+/// represent anything that has two dimensions: a size, a point,
+/// a velocity, etc.
+///
+/// The template parameter T is the type of the coordinates. It
+/// can be any type that supports arithmetic operations (+, -, /, *)
+/// and comparisons (==, !=), for example int or float.
+///
+/// You generally don't have to care about the templated form (sf::Vector2<T>),
+/// the most common specializations have special typedefs:
+/// \li sf::Vector2<float> is sf::Vector2f
+/// \li sf::Vector2<int> is sf::Vector2i
+/// \li sf::Vector2<unsigned int> is sf::Vector2u
+///
+/// The sf::Vector2 class has a small and simple interface, its x and y members
+/// can be accessed directly (there are no accessors like setX(), getX()) and it
+/// contains no mathematical function like dot product, cross product, length, etc.
+///
+/// Usage example:
+/// \code
+/// sf::Vector2f v1(16.5f, 24.f);
+/// v1.x = 18.2f;
+/// float y = v1.y;
+///
+/// sf::Vector2f v2 = v1 * 5.f;
+/// sf::Vector2f v3;
+/// v3 = v1 + v2;
+///
+/// bool different = (v2 != v3);
+/// \endcode
+///
+/// Note: for 3-dimensional vectors, see sf::Vector3.
+///
+////////////////////////////////////////////////////////////
index 3163764d9bb66a62a899cdf871b6319b4a050903..07b96f5a68da64239e902e1e81efac526a04c3e0 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 
 
-////////////////////////////////////////////////////////////
-/// Default constructor
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>::Vector2() :
+inline Vector2<T>::Vector2() :
 x(0),
 y(0)
 {
@@ -35,11 +33,9 @@ y(0)
 }
 
 
-////////////////////////////////////////////////////////////
-/// Construct the color from its coordinates
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>::Vector2(T X, T Y) :
+inline Vector2<T>::Vector2(T X, T Y) :
 x(X),
 y(Y)
 {
@@ -47,133 +43,119 @@ y(Y)
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator - overload ; returns the opposite of a vector
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator -(const Vector2<T>& V)
+template <typename U>
+inline Vector2<T>::Vector2(const Vector2<U>& vector) :
+x(static_cast<T>(vector.x)),
+y(static_cast<T>(vector.y))
 {
-    return Vector2<T>(-V.x, -V.y);
 }
 
 
 ////////////////////////////////////////////////////////////
-/// Operator += overload ; add two vectors and assign to the first op
+template <typename T>
+inline Vector2<T> operator -(const Vector2<T>& right)
+{
+    return Vector2<T>(-right.x, -right.y);
+}
+
+
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator +=(Vector2<T>& V1, const Vector2<T>& V2)
+inline Vector2<T>& operator +=(Vector2<T>& left, const Vector2<T>& right)
 {
-    V1.x += V2.x;
-    V1.y += V2.y;
+    left.x += right.x;
+    left.y += right.y;
 
-    return V1;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator -= overload ; subtract two vectors and assign to the first op
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator -=(Vector2<T>& V1, const Vector2<T>& V2)
+inline Vector2<T>& operator -=(Vector2<T>& left, const Vector2<T>& right)
 {
-    V1.x -= V2.x;
-    V1.y -= V2.y;
+    left.x -= right.x;
+    left.y -= right.y;
 
-    return V1;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator + overload ; adds two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator +(const Vector2<T>& V1, const Vector2<T>& V2)
+inline Vector2<T> operator +(const Vector2<T>& left, const Vector2<T>& right)
 {
-    return Vector2<T>(V1.x + V2.x, V1.y + V2.y);
+    return Vector2<T>(left.x + right.x, left.y + right.y);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator - overload ; subtracts two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator -(const Vector2<T>& V1, const Vector2<T>& V2)
+inline Vector2<T> operator -(const Vector2<T>& left, const Vector2<T>& right)
 {
-    return Vector2<T>(V1.x - V2.x, V1.y - V2.y);
+    return Vector2<T>(left.x - right.x, left.y - right.y);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator *(const Vector2<T>& V, T X)
+inline Vector2<T> operator *(const Vector2<T>& left, T right)
 {
-    return Vector2<T>(V.x * X, V.y * X);
+    return Vector2<T>(left.x * right, left.y * right);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a scalar value by a vector
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator *(T X, const Vector2<T>& V)
+inline Vector2<T> operator *(T left, const Vector2<T>& right)
 {
-    return Vector2<T>(V.x * X, V.y * X);
+    return Vector2<T>(right.x * left, right.y * left);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator *= overload ; multiply-assign a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator *=(Vector2<T>& V, T X)
+inline Vector2<T>& operator *=(Vector2<T>& left, T right)
 {
-    V.x *= X;
-    V.y *= X;
+    left.x *= right;
+    left.y *= right;
 
-    return V;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator / overload ; divide a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T> operator /(const Vector2<T>& V, T X)
+inline Vector2<T> operator /(const Vector2<T>& left, T right)
 {
-    return Vector2<T>(V.x / X, V.y / X);
+    return Vector2<T>(left.x / right, left.y / right);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator /= overload ; divide-assign a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector2<T>& operator /=(Vector2<T>& V, T X)
+inline Vector2<T>& operator /=(Vector2<T>& left, T right)
 {
-    V.x /= X;
-    V.y /= X;
+    left.x /= right;
+    left.y /= right;
 
-    return V;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator == overload ; compares the equality of two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator ==(const Vector2<T>& V1, const Vector2<T>& V2)
+inline bool operator ==(const Vector2<T>& left, const Vector2<T>& right)
 {
-    return (V1.x == V2.x) && (V1.y == V2.y);
+    return (left.x == right.x) && (left.y == right.y);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator != overload ; compares the difference of two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator !=(const Vector2<T>& V1, const Vector2<T>& V2)
+inline bool operator !=(const Vector2<T>& left, const Vector2<T>& right)
 {
-    return (V1.x != V2.x) || (V1.y != V2.y);
+    return (left.x != right.x) || (left.y != right.y);
 }
index 216443ca7f04a3461bfb2a4152cbecbaa936711d..28d0c07603126233f95ae5127e0a52fef09bc539 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Vector3 is an utility class for manipulating 3 dimensional
-/// vectors. Template parameter defines the type of coordinates
-/// (integer, float, ...)
+/// \brief Utility template class for manipulating
+///        3-dimensional vectors
+///
 ////////////////////////////////////////////////////////////
 template <typename T>
 class Vector3
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// Creates a Vector3(0, 0, 0).
     ///
     ////////////////////////////////////////////////////////////
     Vector3();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the vector from its coordinates
+    /// \brief Construct the vector from its coordinates
     ///
-    /// \param X X coordinate
-    /// \param Y Y coordinate
-    /// \param Z Z coordinate
+    /// \param X X coordinate
+    /// \param Y Y coordinate
+    /// \param Z Z coordinate
     ///
     ////////////////////////////////////////////////////////////
     Vector3(T X, T Y, T Z);
 
+    ////////////////////////////////////////////////////////////
+    /// \brief Construct the vector from another type of vector
+    ///
+    /// This constructor doesn't replace the copy constructor,
+    /// it's called only when U != T.
+    /// A call to this constructor will fail to compile if U
+    /// is not convertible to T.
+    ///
+    /// \param vector Vector to convert
+    ///
+    ////////////////////////////////////////////////////////////
+    template <typename U>
+    explicit Vector3(const Vector3<U>& vector);
+
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
@@ -63,147 +79,175 @@ public :
 };
 
 ////////////////////////////////////////////////////////////
-/// Operator - overload ; returns the opposite of a vector
+/// \relates Vector3
+/// \brief Overload of unary operator -
 ///
-/// \param V : Vector to negate
+/// \param left Vector to negate
 ///
-/// \return -V
+/// \return Memberwise opposite of the vector
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator -(const Vector3<T>& V);
+Vector3<T> operator -(const Vector3<T>& left);
 
 ////////////////////////////////////////////////////////////
-/// Operator += overload ; add two vectors and assign to the first op
+/// \relates Vector3
+/// \brief Overload of binary operator +=
+///
+/// This operator performs a memberwise addition of both vectors,
+/// and assigns the result to \a left.
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return V1 + V2
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator +=(Vector3<T>& V1, const Vector3<T>& V2);
+Vector3<T>& operator +=(Vector3<T>& left, const Vector3<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator -= overload ; subtract two vectors and assign to the first op
+/// \relates Vector3
+/// \brief Overload of binary operator -=
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// This operator performs a memberwise subtraction of both vectors,
+/// and assigns the result to \a left.
 ///
-/// \return V1 - V2
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
+///
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator -=(Vector3<T>& V1, const Vector3<T>& V2);
+Vector3<T>& operator -=(Vector3<T>& left, const Vector3<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator + overload ; adds two vectors
+/// \relates Vector3
+/// \brief Overload of binary operator +
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return V1 + V2
+/// \return Memberwise addition of both vectors
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator +(const Vector3<T>& V1, const Vector3<T>& V2);
+Vector3<T> operator +(const Vector3<T>& left, const Vector3<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator - overload ; subtracts two vectors
+/// \relates Vector3
+/// \brief Overload of binary operator -
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return V1 - V2
+/// \return Memberwise subtraction of both vectors
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator -(const Vector3<T>& V1, const Vector3<T>& V2);
+Vector3<T> operator -(const Vector3<T>& left, const Vector3<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a vector by a scalar value
+/// \relates Vector3
+/// \brief Overload of binary operator *
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
 ///
-/// \return V * X
+/// \return Memberwise multiplication by \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator *(const Vector3<T>& V, T X);
+Vector3<T> operator *(const Vector3<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a scalar value by a vector
+/// \relates Vector3
+/// \brief Overload of binary operator *
 ///
-/// \param X : Scalar value
-/// \param V : Vector
+/// \param left  Left operand (a scalar value)
+/// \param right Right operand (a vector)
 ///
-/// \return X * V
+/// \return Memberwise multiplication by \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator *(T X, const Vector3<T>& V);
+Vector3<T> operator *(T left, const Vector3<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator *= overload ; multiply-assign a vector by a scalar value
+/// \relates Vector3
+/// \brief Overload of binary operator *=
+///
+/// This operator performs a memberwise multiplication by \a right,
+/// and assigns the result to \a left.
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
 ///
-/// \return V * X
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator *=(Vector3<T>& V, T X);
+Vector3<T>& operator *=(Vector3<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator / overload ; divide a vector by a scalar value
+/// \relates Vector3
+/// \brief Overload of binary operator /
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
 ///
-/// \return V / X
+/// \return Memberwise division by \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator /(const Vector3<T>& V, T X);
+Vector3<T> operator /(const Vector3<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator /= overload ; divide-assign a vector by a scalar value
+/// \relates Vector3
+/// \brief Overload of binary operator /=
 ///
-/// \param V : Vector
-/// \param X : Scalar value
+/// This operator performs a memberwise division by \a right,
+/// and assigns the result to \a left.
 ///
-/// \return V / X
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a scalar value)
+///
+/// \return Reference to \a left
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator /=(Vector3<T>& V, T X);
+Vector3<T>& operator /=(Vector3<T>& left, T right);
 
 ////////////////////////////////////////////////////////////
-/// Operator == overload ; compares the equality of two vectors
+/// \relates Vector3
+/// \brief Overload of binary operator ==
+///
+/// This operator compares strict equality between two vectors.
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return True if V1 is equal to V2
+/// \return True if \a left is equal to \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator ==(const Vector3<T>& V1, const Vector3<T>& V2);
+bool operator ==(const Vector3<T>& left, const Vector3<T>& right);
 
 ////////////////////////////////////////////////////////////
-/// Operator != overload ; compares the difference of two vectors
+/// \relates Vector3
+/// \brief Overload of binary operator !=
+///
+/// This operator compares strict difference between two vectors.
 ///
-/// \param V1 : First vector
-/// \param V2 : Second vector
+/// \param left  Left operand (a vector)
+/// \param right Right operand (a vector)
 ///
-/// \return True if V1 is different than V2
+/// \return True if \a left is not equal to \a right
 ///
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator !=(const Vector3<T>& V1, const Vector3<T>& V2);
+bool operator !=(const Vector3<T>& left, const Vector3<T>& right);
 
 #include <SFML/System/Vector3.inl>
 
@@ -215,3 +259,44 @@ typedef Vector3<float> Vector3f;
 
 
 #endif // SFML_VECTOR3_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Vector3
+/// \ingroup system
+///
+/// sf::Vector3 is a simple class that defines a mathematical
+/// vector with three coordinates (x, y and z). It can be used to
+/// represent anything that has three dimensions: a size, a point,
+/// a velocity, etc.
+///
+/// The template parameter T is the type of the coordinates. It
+/// can be any type that supports arithmetic operations (+, -, /, *)
+/// and comparisons (==, !=), for example int or float.
+///
+/// You generally don't have to care about the templated form (sf::Vector3<T>),
+/// the most common specializations have special typedefs:
+/// \li sf::Vector3<float> is sf::Vector3f
+/// \li sf::Vector3<int> is sf::Vector3i
+///
+/// The sf::Vector3 class has a small and simple interface, its x and y members
+/// can be accessed directly (there are no accessors like setX(), getX()) and it
+/// contains no mathematical function like dot product, cross product, length, etc.
+///
+/// Usage example:
+/// \code
+/// sf::Vector3f v1(16.5f, 24.f, -8.2f);
+/// v1.x = 18.2f;
+/// float y = v1.y;
+/// float z = v1.z;
+///
+/// sf::Vector3f v2 = v1 * 5.f;
+/// sf::Vector3f v3;
+/// v3 = v1 + v2;
+///
+/// bool different = (v2 != v3);
+/// \endcode
+///
+/// Note: for 2-dimensional vectors, see sf::Vector2.
+///
+////////////////////////////////////////////////////////////
index 107d80481f2ad32aa0dc78bcc0e5246e2206e81c..af8dae356db4831211a54be222b79bbce053a597 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 
 
-////////////////////////////////////////////////////////////
-/// Default constructor
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>::Vector3() :
+inline Vector3<T>::Vector3() :
 x(0),
 y(0),
 z(0)
@@ -36,11 +34,9 @@ z(0)
 }
 
 
-////////////////////////////////////////////////////////////
-/// Construct the color from its coordinates
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>::Vector3(T X, T Y, T Z) :
+inline Vector3<T>::Vector3(T X, T Y, T Z) :
 x(X),
 y(Y),
 z(Z)
@@ -49,137 +45,124 @@ z(Z)
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator - overload ; returns the opposite of a vector
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator -(const Vector3<T>& V)
+template <typename U>
+inline Vector3<T>::Vector3(const Vector3<U>& vector) :
+x(static_cast<T>(vector.x)),
+y(static_cast<T>(vector.y)),
+z(static_cast<T>(vector.z))
 {
-    return Vector3<T>(-V.x, -V.y, -V.z);
 }
 
 
 ////////////////////////////////////////////////////////////
-/// Operator += overload ; add two vectors and assign to the first op
+template <typename T>
+inline Vector3<T> operator -(const Vector3<T>& left)
+{
+    return Vector3<T>(-left.x, -left.y, -left.z);
+}
+
+
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator +=(Vector3<T>& V1, const Vector3<T>& V2)
+inline Vector3<T>& operator +=(Vector3<T>& left, const Vector3<T>& right)
 {
-    V1.x += V2.x;
-    V1.y += V2.y;
-    V1.z += V2.z;
+    left.x += right.x;
+    left.y += right.y;
+    left.z += right.z;
 
-    return V1;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator -= overload ; subtract two vectors and assign to the first op
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator -=(Vector3<T>& V1, const Vector3<T>& V2)
+inline Vector3<T>& operator -=(Vector3<T>& left, const Vector3<T>& right)
 {
-    V1.x -= V2.x;
-    V1.y -= V2.y;
-    V1.z -= V2.z;
+    left.x -= right.x;
+    left.y -= right.y;
+    left.z -= right.z;
 
-    return V1;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator + overload ; adds two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator +(const Vector3<T>& V1, const Vector3<T>& V2)
+inline Vector3<T> operator +(const Vector3<T>& left, const Vector3<T>& right)
 {
-    return Vector3<T>(V1.x + V2.x, V1.y + V2.y, V1.z + V2.z);
+    return Vector3<T>(left.x + right.x, left.y + right.y, left.z + right.z);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator - overload ; subtracts two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator -(const Vector3<T>& V1, const Vector3<T>& V2)
+inline Vector3<T> operator -(const Vector3<T>& left, const Vector3<T>& right)
 {
-    return Vector3<T>(V1.x - V2.x, V1.y - V2.y, V1.z - V2.z);
+    return Vector3<T>(left.x - right.x, left.y - right.y, left.z - right.z);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator *(const Vector3<T>& V, T X)
+inline Vector3<T> operator *(const Vector3<T>& left, T right)
 {
-    return Vector3<T>(V.x * X, V.y * X, V.z * X);
+    return Vector3<T>(left.x * right, left.y * right, left.z * right);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator * overload ; multiply a scalar value by a vector
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator *(T X, const Vector3<T>& V)
+inline Vector3<T> operator *(T left, const Vector3<T>& right)
 {
-    return Vector3<T>(V.x * X, V.y * X, V.z * X);
+    return Vector3<T>(right.x * left, right.y * left, right.z * left);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator *= overload ; multiply-assign a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator *=(Vector3<T>& V, T X)
+inline Vector3<T>& operator *=(Vector3<T>& left, T right)
 {
-    V.x *= X;
-    V.y *= X;
-    V.z *= X;
+    left.x *= right;
+    left.y *= right;
+    left.z *= right;
 
-    return V;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator / overload ; divide a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T> operator /(const Vector3<T>& V, T X)
+inline Vector3<T> operator /(const Vector3<T>& left, T right)
 {
-    return Vector3<T>(V.x / X, V.y / X, V.z / X);
+    return Vector3<T>(left.x / right, left.y / right, left.z / right);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator /= overload ; divide-assign a vector by a scalar value
 ////////////////////////////////////////////////////////////
 template <typename T>
-Vector3<T>& operator /=(Vector3<T>& V, T X)
+inline Vector3<T>& operator /=(Vector3<T>& left, T right)
 {
-    V.x /= X;
-    V.y /= X;
-    V.z /= X;
+    left.x /= right;
+    left.y /= right;
+    left.z /= right;
 
-    return V;
+    return left;
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator == overload ; compares the equality of two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator ==(const Vector3<T>& V1, const Vector3<T>& V2)
+inline bool operator ==(const Vector3<T>& left, const Vector3<T>& right)
 {
-    return (V1.x == V2.x) && (V1.y == V2.y) && (V1.z == V2.z);
+    return (left.x == right.x) && (left.y == right.y) && (left.z == right.z);
 }
 
 
-////////////////////////////////////////////////////////////
-/// Operator != overload ; compares the difference of two vectors
 ////////////////////////////////////////////////////////////
 template <typename T>
-bool operator !=(const Vector3<T>& V1, const Vector3<T>& V2)
+inline bool operator !=(const Vector3<T>& left, const Vector3<T>& right)
 {
-    return (V1.x != V2.x) || (V1.y != V2.y) || (V1.z != V2.z);
+    return (left.x != right.x) || (left.y != right.y) || (left.z != right.z);
 }
index 26c731f2e8c1c9ae9d1ceab57769a9b94f6a47bd..30b317ba838640b1caac4be34c04845ec221e56c 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 
 #include <SFML/System.hpp>
 #include <SFML/Window/Context.hpp>
+#include <SFML/Window/ContextSettings.hpp>
 #include <SFML/Window/Event.hpp>
-#include <SFML/Window/Input.hpp>
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
+#include <SFML/Window/Touch.hpp>
+#include <SFML/Window/Sensor.hpp>
 #include <SFML/Window/VideoMode.hpp>
 #include <SFML/Window/Window.hpp>
-#include <SFML/Window/WindowListener.hpp>
 #include <SFML/Window/WindowStyle.hpp>
-#include <SFML/Window/OpenGL.hpp>
+
 
 
 #endif // SFML_SFML_WINDOW_HPP
+
+////////////////////////////////////////////////////////////
+/// \defgroup window Window module
+///
+/// Provides OpenGL-based windows, and abstractions for
+/// events and input handling.
+///
+////////////////////////////////////////////////////////////
index 9d06d7228c18ba4b03f84f57229b23b5266446c0..595d4d69e9e9f4b0c4ca15760fd212294acdd386 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
@@ -28,7 +28,9 @@
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/Window/Export.hpp>
+#include <SFML/Window/GlResource.hpp>
+#include <SFML/Window/ContextSettings.hpp>
 #include <SFML/System/NonCopyable.hpp>
 
 
@@ -36,65 +38,103 @@ namespace sf
 {
 namespace priv
 {
-    class WindowImpl;
+    class GlContext;
 }
 
 ////////////////////////////////////////////////////////////
-/// Class wrapping an OpenGL context.
-/// All SFML windows already have their own context, so
-/// this class is more a helper for specific issues involving
-/// OpenGL and multi-threading.
-/// It's meant to be used internally.
+/// \brief Class holding a valid drawing context
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Context : NonCopyable
+class SFML_WINDOW_API Context : GlResource, NonCopyable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor, create the context
+    /// \brief Default constructor
+    ///
+    /// The constructor creates and activates the context
     ///
     ////////////////////////////////////////////////////////////
     Context();
 
     ////////////////////////////////////////////////////////////
-    /// Destructor, destroy the context
+    /// \brief Destructor
+    ///
+    /// The destructor deactivates and destroys the context
     ///
     ////////////////////////////////////////////////////////////
     ~Context();
 
     ////////////////////////////////////////////////////////////
-    /// Activate or deactivate the context
-    ///
-    /// \param Active : True to activate the context, false to deactivate it
+    /// \brief Activate or deactivate explicitly the context
     ///
-    ////////////////////////////////////////////////////////////
-    void SetActive(bool Active);
-
-    ////////////////////////////////////////////////////////////
-    /// Check if there's a context bound to the current thread
+    /// \param active True to activate, false to deactivate
     ///
-    /// \return True if there's a context bound to the current thread
+    /// \return True on success, false on failure
     ///
     ////////////////////////////////////////////////////////////
-    static bool IsContextActive();
+    bool setActive(bool active);
+
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Get the global context
+    /// \brief Construct a in-memory context
+    ///
+    /// This constructor is for internal use, you don't need
+    /// to bother with it.
     ///
-    /// \return Reference to the global context
+    /// \param settings Creation parameters
+    /// \param width    Back buffer width
+    /// \param height   Back buffer height
     ///
     ////////////////////////////////////////////////////////////
-    static Context& GetGlobal();
+    Context(const ContextSettings& settings, unsigned int width, unsigned int height);
 
-private :
+private:
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    priv::WindowImpl* myDummyWindow; ///< Dummy window holding the context
+    priv::GlContext* m_context; ///< Internal OpenGL context
 };
 
 } // namespace sf
 
 
 #endif // SFML_CONTEXT_HPP
+
+////////////////////////////////////////////////////////////
+/// \class sf::Context
+/// \ingroup window
+///
+/// If you need to make OpenGL calls without having an
+/// active window (like in a thread), you can use an
+/// instance of this class to get a valid context.
+///
+/// Having a valid context is necessary for *every* OpenGL call.
+///
+/// Note that a context is only active in its current thread,
+/// if you create a new thread it will have no valid context
+/// by default.
+///
+/// To use a sf::Context instance, just construct it and let it
+/// live as long as you need a valid context. No explicit activation
+/// is needed, all it has to do is to exist. Its destructor
+/// will take care of deactivating and freeing all the attached
+/// resources.
+///
+/// Usage example:
+/// \code
+/// void threadFunction(void*)
+/// {
+///    sf::Context context;
+///    // from now on, you have a valid context
+///
+///    // you can make OpenGL calls
+///    glClear(GL_DEPTH_BUFFER_BIT);
+/// }
+/// // the context is automatically deactivated and destroyed
+/// // by the sf::Context destructor
+/// \endcode
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/ContextSettings.hpp b/dependencies64/sfml/include/SFML/Window/ContextSettings.hpp
new file mode 100644 (file)
index 0000000..da89b2f
--- /dev/null
@@ -0,0 +1,104 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_CONTEXTSETTINGS_HPP
+#define SFML_CONTEXTSETTINGS_HPP
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Structure defining the settings of the OpenGL
+///        context attached to a window
+///
+////////////////////////////////////////////////////////////
+struct ContextSettings
+{
+    ////////////////////////////////////////////////////////////
+    /// \brief Default constructor
+    ///
+    /// \param depth        Depth buffer bits
+    /// \param stencil      Stencil buffer bits
+    /// \param antialiasing Antialiasing level
+    /// \param major        Major number of the context version
+    /// \param minor        Minor number of the context version
+    ///
+    ////////////////////////////////////////////////////////////
+    explicit ContextSettings(unsigned int depth = 0, unsigned int stencil = 0, unsigned int antialiasing = 0, unsigned int major = 2, unsigned int minor = 0) :
+    depthBits        (depth),
+    stencilBits      (stencil),
+    antialiasingLevel(antialiasing),
+    majorVersion     (major),
+    minorVersion     (minor)
+    {
+    }
+
+    ////////////////////////////////////////////////////////////
+    // Member data
+    ////////////////////////////////////////////////////////////
+    unsigned int depthBits;         ///< Bits of the depth buffer
+    unsigned int stencilBits;       ///< Bits of the stencil buffer
+    unsigned int antialiasingLevel; ///< Level of antialiasing
+    unsigned int majorVersion;      ///< Major number of the context version to create
+    unsigned int minorVersion;      ///< Minor number of the context version to create
+};
+
+} // namespace sf
+
+
+#endif // SFML_CONTEXTSETTINGS_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::ContextSettings
+/// \ingroup window
+///
+/// ContextSettings allows to define several advanced settings
+/// of the OpenGL context attached to a window. All these
+/// settings have no impact on the regular SFML rendering
+/// (graphics module) -- except the anti-aliasing level, so
+/// you may need to use this structure only if you're using
+/// SFML as a windowing system for custom OpenGL rendering.
+///
+/// The depthBits and stencilBits members define the number
+/// of bits per pixel requested for the (respectively) depth
+/// and stencil buffers.
+///
+/// antialiasingLevel represents the requested number of
+/// multisampling levels for anti-aliasing.
+///
+/// majorVersion and minorVersion define the version of the
+/// OpenGL context that you want. Only versions greater or
+/// equal to 3.0 are relevant; versions lesser than 3.0 are
+/// all handled the same way (i.e. you can use any version
+/// < 3.0 if you don't want an OpenGL 3 context).
+///
+/// Please note that these values are only a hint.
+/// No failure will be reported if one or more of these values
+/// are not supported by the system; instead, SFML will try to
+/// find the closest valid match. You can then retrieve the
+/// settings that the window actually used to create its context,
+/// with Window::getSettings().
+///
+////////////////////////////////////////////////////////////
index 35ac5755377207d7be3fcacb20e3f3a0edb51bbf..7499a052261e2a4c9e2f6882a9f8d89af14fa64e 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 // Headers
 ////////////////////////////////////////////////////////////
 #include <SFML/Config.hpp>
+#include <SFML/Window/Joystick.hpp>
+#include <SFML/Window/Keyboard.hpp>
+#include <SFML/Window/Mouse.hpp>
+#include <SFML/Window/Sensor.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Definition of key codes for keyboard events
+/// \brief Defines a system event and its parameters
+///
 ////////////////////////////////////////////////////////////
-namespace Key
-{
-    enum Code
-    {
-        A = 'a',
-        B = 'b',
-        C = 'c',
-        D = 'd',
-        E = 'e',
-        F = 'f',
-        G = 'g',
-        H = 'h',
-        I = 'i',
-        J = 'j',
-        K = 'k',
-        L = 'l',
-        M = 'm',
-        N = 'n',
-        O = 'o',
-        P = 'p',
-        Q = 'q',
-        R = 'r',
-        S = 's',
-        T = 't',
-        U = 'u',
-        V = 'v',
-        W = 'w',
-        X = 'x',
-        Y = 'y',
-        Z = 'z',
-        Num0 = '0',
-        Num1 = '1',
-        Num2 = '2',
-        Num3 = '3',
-        Num4 = '4',
-        Num5 = '5',
-        Num6 = '6',
-        Num7 = '7',
-        Num8 = '8',
-        Num9 = '9', 
-        Escape = 256,
-        LControl,
-        LShift,
-        LAlt,
-        LSystem,      ///< OS specific key (left side) : windows (Win and Linux), apple (MacOS), ...
-        RControl,
-        RShift,
-        RAlt,
-        RSystem,      ///< OS specific key (right side) : windows (Win and Linux), apple (MacOS), ...
-        Menu,
-        LBracket,     ///< [
-        RBracket,     ///< ]
-        SemiColon,    ///< ;
-        Comma,        ///< ,
-        Period,       ///< .
-        Quote,        ///< '
-        Slash,        ///< /
-        BackSlash,
-        Tilde,        ///< ~
-        Equal,        ///< =
-        Dash,         ///< -
-        Space,
-        Return,
-        Back,
-        Tab,
-        PageUp,
-        PageDown,
-        End,
-        Home,
-        Insert,
-        Delete,
-        Add,          ///< +
-        Subtract,     ///< -
-        Multiply,     ///< *
-        Divide,       ///< /
-        Left,         ///< Left arrow
-        Right,        ///< Right arrow
-        Up,           ///< Up arrow
-        Down,         ///< Down arrow
-        Numpad0,
-        Numpad1,
-        Numpad2,
-        Numpad3,
-        Numpad4,
-        Numpad5,
-        Numpad6,
-        Numpad7,
-        Numpad8,
-        Numpad9,
-        F1,
-        F2,
-        F3,
-        F4,
-        F5,
-        F6,
-        F7,
-        F8,
-        F9,
-        F10,
-        F11,
-        F12,
-        F13,
-        F14,
-        F15,
-        Pause,
-
-        Count // Keep last -- total number of keyboard keys
-    };
-}
-
-
-////////////////////////////////////////////////////////////
-/// Definition of button codes for mouse events
-////////////////////////////////////////////////////////////
-namespace Mouse
-{
-    enum Button
-    {
-        Left,
-        Right,
-        Middle,
-        XButton1,
-        XButton2,
-
-        ButtonCount // Keep last -- total number of mouse buttons
-    };
-}
-
-
-////////////////////////////////////////////////////////////
-/// Definition of joystick axis for joystick events
-////////////////////////////////////////////////////////////
-namespace Joy
+class Event
 {
-    enum Axis
-    {
-        AxisX,
-        AxisY,
-        AxisZ,
-        AxisR,
-        AxisU,
-        AxisV,
-        AxisPOV,
-
-        AxisCount // Keep last -- total number of joystick axis
-    };
+public:
 
-    enum
+    ////////////////////////////////////////////////////////////
+    /// \brief Size events parameters (Resized)
+    ///
+    ////////////////////////////////////////////////////////////
+    struct SizeEvent
     {
-        Count       = 4, ///< Total number of supported joysticks
-        ButtonCount = 32 ///< Total number of supported joystick buttons
+        unsigned int width;  ///< New width, in pixels
+        unsigned int height; ///< New height, in pixels
     };
-}
-
-
-////////////////////////////////////////////////////////////
-/// Event defines a system event and its parameters
-////////////////////////////////////////////////////////////
-class Event
-{
-public :
 
     ////////////////////////////////////////////////////////////
-    /// Keyboard event parameters
+    /// \brief Keyboard event parameters (KeyPressed, KeyReleased)
+    ///
     ////////////////////////////////////////////////////////////
     struct KeyEvent
     {
-        Key::Code Code;
-        bool      Alt;
-        bool      Control;
-        bool      Shift;
+        Keyboard::Key code;    ///< Code of the key that has been pressed
+        bool          alt;     ///< Is the Alt key pressed?
+        bool          control; ///< Is the Control key pressed?
+        bool          shift;   ///< Is the Shift key pressed?
+        bool          system;  ///< Is the System key pressed?
     };
 
     ////////////////////////////////////////////////////////////
-    /// Text event parameters
+    /// \brief Text event parameters (TextEntered)
+    ///
     ////////////////////////////////////////////////////////////
     struct TextEvent
     {
-        Uint32 Unicode;
+        Uint32 unicode; ///< UTF-32 Unicode value of the character
     };
 
     ////////////////////////////////////////////////////////////
-    /// Mouse move event parameters
+    /// \brief Mouse move event parameters (MouseMoved)
+    ///
     ////////////////////////////////////////////////////////////
     struct MouseMoveEvent
     {
-        int X;
-        int Y;
+        int x; ///< X position of the mouse pointer, relative to the left of the owner window
+        int y; ///< Y position of the mouse pointer, relative to the top of the owner window
     };
 
     ////////////////////////////////////////////////////////////
-    /// Mouse buttons events parameters
+    /// \brief Mouse buttons events parameters
+    ///        (MouseButtonPressed, MouseButtonReleased)
+    ///
     ////////////////////////////////////////////////////////////
     struct MouseButtonEvent
     {
-        Mouse::Button Button;
-        int           X;
-        int           Y;
+        Mouse::Button button; ///< Code of the button that has been pressed
+        int           x;      ///< X position of the mouse pointer, relative to the left of the owner window
+        int           y;      ///< Y position of the mouse pointer, relative to the top of the owner window
     };
 
     ////////////////////////////////////////////////////////////
-    /// Mouse wheel events parameters
+    /// \brief Mouse wheel events parameters (MouseWheelMoved)
+    ///
     ////////////////////////////////////////////////////////////
     struct MouseWheelEvent
     {
-        int Delta;
+        int delta; ///< Number of ticks the wheel has moved (positive is up, negative is down)
+        int x;     ///< X position of the mouse pointer, relative to the left of the owner window
+        int y;     ///< Y position of the mouse pointer, relative to the top of the owner window
     };
 
     ////////////////////////////////////////////////////////////
-    /// Joystick axis move event parameters
+    /// \brief Joystick connection events parameters
+    ///        (JoystickConnected, JoystickDisconnected)
+    ///
     ////////////////////////////////////////////////////////////
-    struct JoyMoveEvent
+    struct JoystickConnectEvent
     {
-        unsigned int JoystickId;
-        Joy::Axis    Axis;
-        float        Position;
+        unsigned int joystickId; ///< Index of the joystick (in range [0 .. Joystick::Count - 1])
     };
 
     ////////////////////////////////////////////////////////////
-    /// Joystick buttons events parameters
+    /// \brief Joystick axis move event parameters (JoystickMoved)
+    ///
     ////////////////////////////////////////////////////////////
-    struct JoyButtonEvent
+    struct JoystickMoveEvent
     {
-        unsigned int JoystickId;
-        unsigned int Button;
+        unsigned int   joystickId; ///< Index of the joystick (in range [0 .. Joystick::Count - 1])
+        Joystick::Axis axis;       ///< Axis on which the joystick moved
+        float          position;   ///< New position on the axis (in range [-100 .. 100])
     };
 
     ////////////////////////////////////////////////////////////
-    /// Size events parameters
+    /// \brief Joystick buttons events parameters
+    ///        (JoystickButtonPressed, JoystickButtonReleased)
+    ///
     ////////////////////////////////////////////////////////////
-    struct SizeEvent
+    struct JoystickButtonEvent
     {
-        unsigned int Width;
-        unsigned int Height;
+        unsigned int joystickId; ///< Index of the joystick (in range [0 .. Joystick::Count - 1])
+        unsigned int button;     ///< Index of the button that has been pressed (in range [0 .. Joystick::ButtonCount - 1])
     };
 
     ////////////////////////////////////////////////////////////
-    /// Enumeration of the different types of events
+    /// \brief Touch events parameters (TouchBegan, TouchMoved, TouchEnded)
+    ///
+    ////////////////////////////////////////////////////////////
+    struct TouchEvent
+    {
+        unsigned int finger; ///< Index of the finger in case of multi-touch events
+        int x;               ///< X position of the touch, relative to the left of the owner window
+        int y;               ///< Y position of the touch, relative to the top of the owner window
+    };
+    
+    ////////////////////////////////////////////////////////////
+    /// \brief Sensor event parameters (SensorChanged)
+    ///
+    ////////////////////////////////////////////////////////////
+    struct SensorEvent
+    {
+               Sensor::Type type; ///< Type of the sensor
+               float x;           ///< Current value of the sensor on X axis
+               float y;           ///< Current value of the sensor on Y axis
+               float z;           ///< Current value of the sensor on Z axis
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enumeration of the different types of events
+    ///
     ////////////////////////////////////////////////////////////
     enum EventType
     {
-        Closed,
-        Resized,
-        LostFocus,
-        GainedFocus,
-        TextEntered,
-        KeyPressed,
-        KeyReleased,
-        MouseWheelMoved,
-        MouseButtonPressed,
-        MouseButtonReleased,
-        MouseMoved,
-        MouseEntered,
-        MouseLeft,
-        JoyButtonPressed,
-        JoyButtonReleased,
-        JoyMoved,
+        Closed,                 ///< The window requested to be closed (no data)
+        Resized,                ///< The window was resized (data in event.size)
+        LostFocus,              ///< The window lost the focus (no data)
+        GainedFocus,            ///< The window gained the focus (no data)
+        TextEntered,            ///< A character was entered (data in event.text)
+        KeyPressed,             ///< A key was pressed (data in event.key)
+        KeyReleased,            ///< A key was released (data in event.key)
+        MouseWheelMoved,        ///< The mouse wheel was scrolled (data in event.mouseWheel)
+        MouseButtonPressed,     ///< A mouse button was pressed (data in event.mouseButton)
+        MouseButtonReleased,    ///< A mouse button was released (data in event.mouseButton)
+        MouseMoved,             ///< The mouse cursor moved (data in event.mouseMove)
+        MouseEntered,           ///< The mouse cursor entered the area of the window (no data)
+        MouseLeft,              ///< The mouse cursor left the area of the window (no data)
+        JoystickButtonPressed,  ///< A joystick button was pressed (data in event.joystickButton)
+        JoystickButtonReleased, ///< A joystick button was released (data in event.joystickButton)
+        JoystickMoved,          ///< The joystick moved along an axis (data in event.joystickMove)
+        JoystickConnected,      ///< A joystick was connected (data in event.joystickConnect)
+        JoystickDisconnected,   ///< A joystick was disconnected (data in event.joystickConnect)
+        TouchBegan,             ///< A touch event began (data in event.touch)
+        TouchMoved,             ///< A touch moved (data in event.touch)
+        TouchEnded,             ///< A touch event ended (data in event.touch)
+        SensorChanged,          ///< A sensor value changed (data in event.sensor)
 
-        Count // Keep last -- total number of event types
+        Count                   ///< Keep last -- the total number of event types
     };
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    EventType Type; ///< Type of the event
+    EventType type; ///< Type of the event
 
     union
     {
-        KeyEvent         Key;
-        TextEvent        Text;
-        MouseMoveEvent   MouseMove;
-        MouseButtonEvent MouseButton;
-        MouseWheelEvent  MouseWheel;
-        JoyMoveEvent     JoyMove;
-        JoyButtonEvent   JoyButton;
-        SizeEvent        Size;
+        SizeEvent            size;            ///< Size event parameters (Event::Resized)
+        KeyEvent             key;             ///< Key event parameters (Event::KeyPressed, Event::KeyReleased)
+        TextEvent            text;            ///< Text event parameters (Event::TextEntered)
+        MouseMoveEvent       mouseMove;       ///< Mouse move event parameters (Event::MouseMoved)
+        MouseButtonEvent     mouseButton;     ///< Mouse button event parameters (Event::MouseButtonPressed, Event::MouseButtonReleased)
+        MouseWheelEvent      mouseWheel;      ///< Mouse wheel event parameters (Event::MouseWheelMoved)
+        JoystickMoveEvent    joystickMove;    ///< Joystick move event parameters (Event::JoystickMoved)
+        JoystickButtonEvent  joystickButton;  ///< Joystick button event parameters (Event::JoystickButtonPressed, Event::JoystickButtonReleased)
+        JoystickConnectEvent joystickConnect; ///< Joystick (dis)connect event parameters (Event::JoystickConnected, Event::JoystickDisconnected)
+        TouchEvent           touch;           ///< Touch events parameters (Event::TouchBegan, Event::TouchMoved, Event::TouchEnded)
+        SensorEvent          sensor;          ///< Sensor event parameters (Event::SensorChanged)
     };
 };
 
@@ -319,3 +222,46 @@ public :
 
 
 #endif // SFML_EVENT_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Event
+/// \ingroup window
+///
+/// sf::Event holds all the informations about a system event
+/// that just happened. Events are retrieved using the
+/// sf::Window::pollEvent and sf::Window::waitEvent functions.
+///
+/// A sf::Event instance contains the type of the event
+/// (mouse moved, key pressed, window closed, ...) as well
+/// as the details about this particular event. Please note that
+/// the event parameters are defined in a union, which means that
+/// only the member matching the type of the event will be properly
+/// filled; all other members will have undefined values and must not
+/// be read if the type of the event doesn't match. For example,
+/// if you received a KeyPressed event, then you must read the
+/// event.key member, all other members such as event.MouseMove
+/// or event.text will have undefined values.
+///
+/// Usage example:
+/// \code
+/// sf::Event event;
+/// while (window.pollEvent(event))
+/// {
+///     // Request for closing the window
+///     if (event.type == sf::Event::Closed)
+///         window.close();
+///
+///     // The escape key was pressed
+///     if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
+///         window.close();
+///
+///     // The window was resized
+///     if (event.type == sf::Event::Resized)
+///         doSomethingWithTheNewSize(event.size.width, event.size.height);
+///
+///     // etc ...
+/// }
+/// \endcode
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/Export.hpp b/dependencies64/sfml/include/SFML/Window/Export.hpp
new file mode 100644 (file)
index 0000000..8df4d51
--- /dev/null
@@ -0,0 +1,48 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_WINDOW_EXPORT_HPP
+#define SFML_WINDOW_EXPORT_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_WINDOW_EXPORTS)
+
+    #define SFML_WINDOW_API SFML_API_EXPORT
+
+#else
+
+    #define SFML_WINDOW_API SFML_API_IMPORT
+
+#endif
+
+
+#endif // SFML_WINDOW_EXPORT_HPP
similarity index 67%
rename from dependencies64/sfml/include/SFML/Audio/AudioResource.hpp
rename to dependencies64/sfml/include/SFML/Window/GlResource.hpp
index 86a5a15d11100ec459bb57900acc5b3b25805ce4..47970fb45b5f5832a523f1115f07089e4609a2bd 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 //
 ////////////////////////////////////////////////////////////
 
-#ifndef SFML_AUDIORESOURCE_HPP
-#define SFML_AUDIORESOURCE_HPP
+#ifndef SFML_GLRESOURCE_HPP
+#define SFML_GLRESOURCE_HPP
 
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
+#include <SFML/Window/Export.hpp>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// Abstract base class for every class that owns a
-/// device-dependant resource -- allow them to initialize / shutdown
-/// even when the audio context is not created
+/// \brief Base class for classes that require an OpenGL context
+///
 ////////////////////////////////////////////////////////////
-class SFML_API AudioResource
+class SFML_WINDOW_API GlResource
 {
-protected :
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
     ///
     ////////////////////////////////////////////////////////////
-    AudioResource();
+    GlResource();
 
     ////////////////////////////////////////////////////////////
-    /// Copy constructor
+    /// \brief Destructor
     ///
     ////////////////////////////////////////////////////////////
-    AudioResource(const AudioResource&);
+    ~GlResource();
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Make sure that a valid OpenGL context exists in the current thread
     ///
     ////////////////////////////////////////////////////////////
-    virtual ~AudioResource();
+    static void ensureGlContext();
 };
 
 } // namespace sf
 
 
-#endif // SFML_AUDIORESOURCE_HPP
+#endif // SFML_GLRESOURCE_HPP
+
+////////////////////////////////////////////////////////////
+/// \class sf::GlResource
+/// \ingroup window
+///
+/// This class is for internal use only, it must be the base
+/// of every class that requires a valid OpenGL context in
+/// order to work.
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/Input.hpp b/dependencies64/sfml/include/SFML/Window/Input.hpp
deleted file mode 100644 (file)
index 1a11977..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-////////////////////////////////////////////////////////////
-//
-// SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
-//
-// This software is provided 'as-is', without any express or implied warranty.
-// In no event will the authors be held liable for any damages arising from the use of this software.
-//
-// Permission is granted to anyone to use this software for any purpose,
-// including commercial applications, and to alter it and redistribute it freely,
-// subject to the following restrictions:
-//
-// 1. The origin of this software must not be misrepresented;
-//    you must not claim that you wrote the original software.
-//    If you use this software in a product, an acknowledgment
-//    in the product documentation would be appreciated but is not required.
-//
-// 2. Altered source versions must be plainly marked as such,
-//    and must not be misrepresented as being the original software.
-//
-// 3. This notice may not be removed or altered from any source distribution.
-//
-////////////////////////////////////////////////////////////
-
-#ifndef SFML_INPUT_HPP
-#define SFML_INPUT_HPP
-
-////////////////////////////////////////////////////////////
-// Headers
-////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-#include <SFML/System/NonCopyable.hpp>
-#include <SFML/Window/Event.hpp>
-#include <SFML/Window/WindowListener.hpp>
-
-
-namespace sf
-{
-////////////////////////////////////////////////////////////
-/// Input handles real-time input from keyboard and mouse.
-/// Use it instead of events to handle continuous moves and more
-/// game-friendly inputs
-////////////////////////////////////////////////////////////
-class SFML_API Input : public WindowListener, NonCopyable
-{
-public :
-
-    ////////////////////////////////////////////////////////////
-    /// Default constructor
-    ///
-    ////////////////////////////////////////////////////////////
-    Input();
-
-    ////////////////////////////////////////////////////////////
-    /// Get the state of a key
-    ///
-    /// \param KeyCode : Key to check
-    ///
-    /// \return True if key is down, false if key is up
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsKeyDown(Key::Code KeyCode) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the state of a mouse button
-    ///
-    /// \param Button : Button to check
-    ///
-    /// \return True if button is down, false if button is up
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsMouseButtonDown(Mouse::Button Button) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the state of a joystick button
-    ///
-    /// \param JoyId :  Identifier of the joystick to check (0 or 1)
-    /// \param Button : Button to check
-    ///
-    /// \return True if button is down, false if button is up
-    ///
-    ////////////////////////////////////////////////////////////
-    bool IsJoystickButtonDown(unsigned int JoyId, unsigned int Button) const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the mouse X position
-    ///
-    /// \return Current mouse left position, relative to owner window
-    ///
-    ////////////////////////////////////////////////////////////
-    int GetMouseX() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get the mouse Y position
-    ///
-    /// \return Current mouse top position, relative to owner window
-    ///
-    ////////////////////////////////////////////////////////////
-    int GetMouseY() const;
-
-    ////////////////////////////////////////////////////////////
-    /// Get a joystick axis position
-    ///
-    /// \param JoyId : Identifier of the joystick to check (0 or 1)
-    /// \param Axis :  Axis to get
-    ///
-    /// \return Current axis position, in the range [-100, 100] (except for POV, which is [0, 360])
-    ///
-    ////////////////////////////////////////////////////////////
-    float GetJoystickAxis(unsigned int JoyId, Joy::Axis Axis) const;
-
-private :
-
-    ////////////////////////////////////////////////////////////
-    /// /see WindowListener::OnEvent
-    ///
-    ////////////////////////////////////////////////////////////
-    virtual void OnEvent(const Event& EventReceived);
-
-    ////////////////////////////////////////////////////////////
-    /// Reset all the states
-    ///
-    ////////////////////////////////////////////////////////////
-    void ResetStates();
-
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    bool  myKeys[Key::Count];                              ///< Array containing the state of all keyboard keys
-    bool  myMouseButtons[Mouse::ButtonCount];              ///< Array containing the state of all mouse buttons
-    int   myMouseX;                                        ///< Mouse position on X
-    int   myMouseY;                                        ///< Mouse position on Y
-    bool  myJoystickButtons[Joy::Count][Joy::ButtonCount]; ///< Array containing the state of all joysticks buttons
-    float myJoystickAxis[Joy::Count][Joy::AxisCount];      ///< Joysticks position on each axis
-};
-
-} // namespace sf
-
-
-#endif // SFML_INPUT_HPP
diff --git a/dependencies64/sfml/include/SFML/Window/Joystick.hpp b/dependencies64/sfml/include/SFML/Window/Joystick.hpp
new file mode 100644 (file)
index 0000000..dc6261b
--- /dev/null
@@ -0,0 +1,227 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_JOYSTICK_HPP
+#define SFML_JOYSTICK_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Export.hpp>
+#include <SFML/System/String.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the joysticks
+///
+////////////////////////////////////////////////////////////
+class SFML_WINDOW_API Joystick
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Constants related to joysticks capabilities
+    ///
+    ////////////////////////////////////////////////////////////
+    enum
+    {
+        Count       = 8,  ///< Maximum number of supported joysticks
+        ButtonCount = 32, ///< Maximum number of supported buttons
+        AxisCount   = 8   ///< Maximum number of supported axes
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Axes supported by SFML joysticks
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Axis
+    {
+        X,    ///< The X axis
+        Y,    ///< The Y axis
+        Z,    ///< The Z axis
+        R,    ///< The R axis
+        U,    ///< The U axis
+        V,    ///< The V axis
+        PovX, ///< The X axis of the point-of-view hat
+        PovY  ///< The Y axis of the point-of-view hat
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Structure holding a joystick's identification
+    ///
+    ////////////////////////////////////////////////////////////
+    struct Identification
+    {
+        Identification();
+
+        sf::String   name;      ///< Name of the joystick
+        unsigned int vendorId;  ///< Manufacturer identifier
+        unsigned int productId; ///< Product identifier
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick is connected
+    ///
+    /// \param joystick Index of the joystick to check
+    ///
+    /// \return True if the joystick is connected, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isConnected(unsigned int joystick);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Return the number of buttons supported by a joystick
+    ///
+    /// If the joystick is not connected, this function returns 0.
+    ///
+    /// \param joystick Index of the joystick
+    ///
+    /// \return Number of buttons supported by the joystick
+    ///
+    ////////////////////////////////////////////////////////////
+    static unsigned int getButtonCount(unsigned int joystick);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick supports a given axis
+    ///
+    /// If the joystick is not connected, this function returns false.
+    ///
+    /// \param joystick Index of the joystick
+    /// \param axis     Axis to check
+    ///
+    /// \return True if the joystick supports the axis, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool hasAxis(unsigned int joystick, Axis axis);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a joystick button is pressed
+    ///
+    /// If the joystick is not connected, this function returns false.
+    ///
+    /// \param joystick Index of the joystick
+    /// \param button   Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isButtonPressed(unsigned int joystick, unsigned int button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of a joystick axis
+    ///
+    /// If the joystick is not connected, this function returns 0.
+    ///
+    /// \param joystick Index of the joystick
+    /// \param axis     Axis to check
+    ///
+    /// \return Current position of the axis, in range [-100 .. 100]
+    ///
+    ////////////////////////////////////////////////////////////
+    static float getAxisPosition(unsigned int joystick, Axis axis);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the joystick information
+    ///
+    /// \param joystick Index of the joystick
+    ///
+    /// \return Structure containing joystick information.
+    ///
+    ////////////////////////////////////////////////////////////
+    static Identification getIdentification(unsigned int joystick);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Update the states of all joysticks
+    ///
+    /// This function is used internally by SFML, so you normally
+    /// don't have to call it explicitly. However, you may need to
+    /// call it if you have no window yet (or no window at all):
+    /// in this case the joystick states are not updated automatically.
+    ///
+    ////////////////////////////////////////////////////////////
+    static void update();
+};
+
+} // namespace sf
+
+
+#endif // SFML_JOYSTICK_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Joystick
+/// \ingroup window
+///
+/// sf::Joystick provides an interface to the state of the
+/// joysticks. It only contains static functions, so it's not
+/// meant to be instantiated. Instead, each joystick is identified
+/// by an index that is passed to the functions of this class.
+///
+/// This class allows users to query the state of joysticks at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the JoystickMoved, JoystickButtonPressed
+/// and JoystickButtonReleased events, sf::Joystick can retrieve the
+/// state of axes and buttons of joysticks at any time
+/// (you don't need to store and update a boolean on your side
+/// in order to know if a button is pressed or released), and you
+/// always get the real state of joysticks, even if they are
+/// moved, pressed or released when your window is out of focus
+/// and no event is triggered.
+///
+/// SFML supports:
+/// \li 8 joysticks (sf::Joystick::Count)
+/// \li 32 buttons per joystick (sf::Joystick::ButtonCount)
+/// \li 8 axes per joystick (sf::Joystick::AxisCount)
+///
+/// Unlike the keyboard or mouse, the state of joysticks is sometimes
+/// not directly available (depending on the OS), therefore an update()
+/// function must be called in order to update the current state of
+/// joysticks. When you have a window with event handling, this is done
+/// automatically, you don't need to call anything. But if you have no
+/// window, or if you want to check joysticks state before creating one,
+/// you must call sf::Joystick::update explicitly.
+///
+/// Usage example:
+/// \code
+/// // Is joystick #0 connected?
+/// bool connected = sf::Joystick::isConnected(0);
+///
+/// // How many buttons does joystick #0 support?
+/// unsigned int buttons = sf::Joystick::getButtonCount(0);
+///
+/// // Does joystick #0 define a X axis?
+/// bool hasX = sf::Joystick::hasAxis(0, sf::Joystick::X);
+///
+/// // Is button #2 pressed on joystick #0?
+/// bool pressed = sf::Joystick::isButtonPressed(0, 2);
+///
+/// // What's the current position of the Y axis on joystick #0?
+/// float position = sf::Joystick::getAxisPosition(0, sf::Joystick::Y);
+/// \endcode
+///
+/// \see sf::Keyboard, sf::Mouse
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/Keyboard.hpp b/dependencies64/sfml/include/SFML/Window/Keyboard.hpp
new file mode 100644 (file)
index 0000000..5dd0d63
--- /dev/null
@@ -0,0 +1,224 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_KEYBOARD_HPP
+#define SFML_KEYBOARD_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Export.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the keyboard
+///
+////////////////////////////////////////////////////////////
+class SFML_WINDOW_API Keyboard
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Key codes
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Key
+    {
+        Unknown = -1, ///< Unhandled key
+        A = 0,        ///< The A key
+        B,            ///< The B key
+        C,            ///< The C key
+        D,            ///< The D key
+        E,            ///< The E key
+        F,            ///< The F key
+        G,            ///< The G key
+        H,            ///< The H key
+        I,            ///< The I key
+        J,            ///< The J key
+        K,            ///< The K key
+        L,            ///< The L key
+        M,            ///< The M key
+        N,            ///< The N key
+        O,            ///< The O key
+        P,            ///< The P key
+        Q,            ///< The Q key
+        R,            ///< The R key
+        S,            ///< The S key
+        T,            ///< The T key
+        U,            ///< The U key
+        V,            ///< The V key
+        W,            ///< The W key
+        X,            ///< The X key
+        Y,            ///< The Y key
+        Z,            ///< The Z key
+        Num0,         ///< The 0 key
+        Num1,         ///< The 1 key
+        Num2,         ///< The 2 key
+        Num3,         ///< The 3 key
+        Num4,         ///< The 4 key
+        Num5,         ///< The 5 key
+        Num6,         ///< The 6 key
+        Num7,         ///< The 7 key
+        Num8,         ///< The 8 key
+        Num9,         ///< The 9 key
+        Escape,       ///< The Escape key
+        LControl,     ///< The left Control key
+        LShift,       ///< The left Shift key
+        LAlt,         ///< The left Alt key
+        LSystem,      ///< The left OS specific key: window (Windows and Linux), apple (MacOS X), ...
+        RControl,     ///< The right Control key
+        RShift,       ///< The right Shift key
+        RAlt,         ///< The right Alt key
+        RSystem,      ///< The right OS specific key: window (Windows and Linux), apple (MacOS X), ...
+        Menu,         ///< The Menu key
+        LBracket,     ///< The [ key
+        RBracket,     ///< The ] key
+        SemiColon,    ///< The ; key
+        Comma,        ///< The , key
+        Period,       ///< The . key
+        Quote,        ///< The ' key
+        Slash,        ///< The / key
+        BackSlash,    ///< The \ key
+        Tilde,        ///< The ~ key
+        Equal,        ///< The = key
+        Dash,         ///< The - key
+        Space,        ///< The Space key
+        Return,       ///< The Return key
+        BackSpace,    ///< The Backspace key
+        Tab,          ///< The Tabulation key
+        PageUp,       ///< The Page up key
+        PageDown,     ///< The Page down key
+        End,          ///< The End key
+        Home,         ///< The Home key
+        Insert,       ///< The Insert key
+        Delete,       ///< The Delete key
+        Add,          ///< The + key
+        Subtract,     ///< The - key
+        Multiply,     ///< The * key
+        Divide,       ///< The / key
+        Left,         ///< Left arrow
+        Right,        ///< Right arrow
+        Up,           ///< Up arrow
+        Down,         ///< Down arrow
+        Numpad0,      ///< The numpad 0 key
+        Numpad1,      ///< The numpad 1 key
+        Numpad2,      ///< The numpad 2 key
+        Numpad3,      ///< The numpad 3 key
+        Numpad4,      ///< The numpad 4 key
+        Numpad5,      ///< The numpad 5 key
+        Numpad6,      ///< The numpad 6 key
+        Numpad7,      ///< The numpad 7 key
+        Numpad8,      ///< The numpad 8 key
+        Numpad9,      ///< The numpad 9 key
+        F1,           ///< The F1 key
+        F2,           ///< The F2 key
+        F3,           ///< The F3 key
+        F4,           ///< The F4 key
+        F5,           ///< The F5 key
+        F6,           ///< The F6 key
+        F7,           ///< The F7 key
+        F8,           ///< The F8 key
+        F9,           ///< The F9 key
+        F10,          ///< The F10 key
+        F11,          ///< The F11 key
+        F12,          ///< The F12 key
+        F13,          ///< The F13 key
+        F14,          ///< The F14 key
+        F15,          ///< The F15 key
+        Pause,        ///< The Pause key
+
+        KeyCount      ///< Keep last -- the total number of keyboard keys
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a key is pressed
+    ///
+    /// \param key Key to check
+    ///
+    /// \return True if the key is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isKeyPressed(Key key);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Show or hide the virtual keyboard
+    ///
+    /// Warning: the virtual keyboard is not supported on all
+    /// systems. It will typically be implemented on mobile OSes
+    /// (Android, iOS) but not on desktop OSes (Windows, Linux, ...).
+    ///
+    /// If the virtual keyboard is not available, this function does
+    /// nothing.
+    ///
+    /// \param visible True to show, false to hide
+    ///
+    ////////////////////////////////////////////////////////////
+    static void setVirtualKeyboardVisible(bool visible);
+};
+
+} // namespace sf
+
+
+#endif // SFML_KEYBOARD_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Keyboard
+/// \ingroup window
+///
+/// sf::Keyboard provides an interface to the state of the
+/// keyboard. It only contains static functions (a single
+/// keyboard is assumed), so it's not meant to be instantiated.
+///
+/// This class allows users to query the keyboard state at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the KeyPressed and KeyReleased events,
+/// sf::Keyboard can retrieve the state of a key at any time
+/// (you don't need to store and update a boolean on your side
+/// in order to know if a key is pressed or released), and you
+/// always get the real state of the keyboard, even if keys are
+/// pressed or released when your window is out of focus and no
+/// event is triggered.
+///
+/// Usage example:
+/// \code
+/// if (sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
+/// {
+///     // move left...
+/// }
+/// else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
+/// {
+///     // move right...
+/// }
+/// else if (sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
+/// {
+///     // quit...
+/// }
+/// \endcode
+///
+/// \see sf::Joystick, sf::Mouse, sf::Touch
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/Mouse.hpp b/dependencies64/sfml/include/SFML/Window/Mouse.hpp
new file mode 100644 (file)
index 0000000..022ecc5
--- /dev/null
@@ -0,0 +1,167 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_MOUSE_HPP
+#define SFML_MOUSE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Export.hpp>
+#include <SFML/System/Vector2.hpp>
+
+
+namespace sf
+{
+class Window;
+
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the mouse
+///
+////////////////////////////////////////////////////////////
+class SFML_WINDOW_API Mouse
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Mouse buttons
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Button
+    {
+        Left,       ///< The left mouse button
+        Right,      ///< The right mouse button
+        Middle,     ///< The middle (wheel) mouse button
+        XButton1,   ///< The first extra mouse button
+        XButton2,   ///< The second extra mouse button
+
+        ButtonCount ///< Keep last -- the total number of mouse buttons
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a mouse button is pressed
+    ///
+    /// \param button Button to check
+    ///
+    /// \return True if the button is pressed, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isButtonPressed(Button button);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of the mouse in desktop coordinates
+    ///
+    /// This function returns the global position of the mouse
+    /// cursor on the desktop.
+    ///
+    /// \return Current position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i getPosition();
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of the mouse in window coordinates
+    ///
+    /// This function returns the current position of the mouse
+    /// cursor, relative to the given window.
+    ///
+    /// \param relativeTo Reference window
+    ///
+    /// \return Current position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i getPosition(const Window& relativeTo);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the current position of the mouse in desktop coordinates
+    ///
+    /// This function sets the global position of the mouse
+    /// cursor on the desktop.
+    ///
+    /// \param position New position of the mouse
+    ///
+    ////////////////////////////////////////////////////////////
+    static void setPosition(const Vector2i& position);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Set the current position of the mouse in window coordinates
+    ///
+    /// This function sets the current position of the mouse
+    /// cursor, relative to the given window.
+    ///
+    /// \param position New position of the mouse
+    /// \param relativeTo Reference window
+    ///
+    ////////////////////////////////////////////////////////////
+    static void setPosition(const Vector2i& position, const Window& relativeTo);
+};
+
+} // namespace sf
+
+
+#endif // SFML_MOUSE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Mouse
+/// \ingroup window
+///
+/// sf::Mouse provides an interface to the state of the
+/// mouse. It only contains static functions (a single
+/// mouse is assumed), so it's not meant to be instantiated.
+///
+/// This class allows users to query the mouse state at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the MouseMoved, MouseButtonPressed
+/// and MouseButtonReleased events, sf::Mouse can retrieve the
+/// state of the cursor and the buttons at any time
+/// (you don't need to store and update a boolean on your side
+/// in order to know if a button is pressed or released), and you
+/// always get the real state of the mouse, even if it is
+/// moved, pressed or released when your window is out of focus
+/// and no event is triggered.
+///
+/// The setPosition and getPosition functions can be used to change
+/// or retrieve the current position of the mouse pointer. There are
+/// two versions: one that operates in global coordinates (relative
+/// to the desktop) and one that operates in window coordinates
+/// (relative to a specific window).
+///
+/// Usage example:
+/// \code
+/// if (sf::Mouse::isButtonPressed(sf::Mouse::Left))
+/// {
+///     // left click...
+/// }
+///
+/// // get global mouse position
+/// sf::Vector2i position = sf::Mouse::getPosition();
+///
+/// // set mouse position relative to a window
+/// sf::Mouse::setPosition(sf::Vector2i(100, 200), window);
+/// \endcode
+///
+/// \see sf::Joystick, sf::Keyboard, sf::Touch
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/Sensor.hpp b/dependencies64/sfml/include/SFML/Window/Sensor.hpp
new file mode 100644 (file)
index 0000000..099dca7
--- /dev/null
@@ -0,0 +1,150 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SENSOR_HPP
+#define SFML_SENSOR_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Export.hpp>
+#include <SFML/System/Vector3.hpp>
+#include <SFML/System/Time.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the sensors
+///
+////////////////////////////////////////////////////////////
+class SFML_WINDOW_API Sensor
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Sensor type
+    ///
+    ////////////////////////////////////////////////////////////
+    enum Type
+    {
+        Accelerometer,    ///< Measures the raw acceleration (m/s²)
+        Gyroscope,        ///< Measures the raw rotation rates (degrees/s)
+        Magnetometer,     ///< Measures the ambient magnetic field (micro-teslas)
+        Gravity,          ///< Measures the direction and intensity of gravity, independent of device acceleration (m/s²)
+        UserAcceleration, ///< Measures the direction and intensity of device acceleration, independent of the gravity (m/s²)
+        Orientation,      ///< Measures the absolute 3D orientation (degrees)
+
+        Count             ///< Keep last -- the total number of sensor types
+    };
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a sensor is available on the underlying platform
+    ///
+    /// \param sensor Sensor to check
+    ///
+    /// \return True if the sensor is available, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isAvailable(Type sensor);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Enable or disable a sensor
+    ///
+    /// All sensors are disabled by default, to avoid consuming too 
+    /// much battery power. Once a sensor is enabled, it starts
+    /// sending events of the corresponding type.
+    ///
+    /// This function does nothing if the sensor is unavailable.
+    ///
+    /// \param sensor  Sensor to enable
+    /// \param enabled True to enable, false to disable
+    ///
+    ////////////////////////////////////////////////////////////
+    static void setEnabled(Type sensor, bool enabled);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current sensor value
+    ///
+    /// \param sensor Sensor to read
+    ///
+    /// \return The current sensor value
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector3f getValue(Type sensor);
+};
+
+} // namespace sf
+
+
+#endif // SFML_SENSOR_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Sensor
+/// \ingroup window
+///
+/// sf::Sensor provides an interface to the state of the
+/// various sensors that a device provides. It only contains static
+/// functions, so it's not meant to be instantiated.
+///
+/// This class allows users to query the sensors values at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the SensorChanged event, sf::Sensor
+/// can retrieve the state of a sensor at any time (you don't need to
+/// store and update its current value on your side).
+///
+/// Depending on the OS and hardware of the device (phone, tablet, ...),
+/// some sensor types may not be available. You should always check
+/// the availability of a sensor before trying to read it, with the
+/// sf::Sensor::isAvailable function.
+///
+/// You may wonder why some sensor types look so similar, for example
+/// Accelerometer and Gravity / UserAcceleration. The first one
+/// is the raw measurement of the acceleration, and takes in account
+/// both the earth gravity and the user movement. The others are
+/// more precise: they provide these components separately, which is
+/// usually more useful. In fact they are not direct sensors, they
+/// are computed internally based on the raw acceleration and other sensors.
+/// This is exactly the same for Gyroscope vs Orientation.
+///
+/// Because sensors consume a non-negligible amount of current, they are
+/// all disabled by default. You must call sf::Sensor::setEnabled for each
+/// sensor in which you are interested.
+///
+/// Usage example:
+/// \code
+/// if (sf::Sensor::isAvailable(sf::Sensor::Gravity))
+/// {
+///     // gravity sensor is available
+/// }
+///
+/// // enable the gravity sensor
+/// sf::Sensor::setEnabled(sf::Sensor::Gravity, true);
+///
+/// // get the current value of gravity
+/// sf::Vector3f gravity = sf::Sensor::getValue(sf::Sensor::Gravity);
+/// \endcode
+///
+////////////////////////////////////////////////////////////
diff --git a/dependencies64/sfml/include/SFML/Window/Touch.hpp b/dependencies64/sfml/include/SFML/Window/Touch.hpp
new file mode 100644 (file)
index 0000000..8d61f1a
--- /dev/null
@@ -0,0 +1,137 @@
+////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2013 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+//    you must not claim that you wrote the original software.
+//    If you use this software in a product, an acknowledgment
+//    in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+//    and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_TOUCH_HPP
+#define SFML_TOUCH_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Window/Export.hpp>
+#include <SFML/System/Vector2.hpp>
+
+
+namespace sf
+{
+class Window;
+
+////////////////////////////////////////////////////////////
+/// \brief Give access to the real-time state of the touches
+///
+////////////////////////////////////////////////////////////
+class SFML_WINDOW_API Touch
+{
+public:
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Check if a touch event is currently down
+    ///
+    /// \param finger Finger index
+    ///
+    /// \return True if \a finger is currently touching the screen, false otherwise
+    ///
+    ////////////////////////////////////////////////////////////
+    static bool isDown(unsigned int finger);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of a touch in desktop coordinates
+    ///
+    /// This function returns the current touch position
+    /// in global (desktop) coordinates.
+    ///
+    /// \param finger Finger index
+    ///
+    /// \return Current position of \a finger, or undefined if it's not down
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i getPosition(unsigned int finger);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the current position of a touch in window coordinates
+    ///
+    /// This function returns the current touch position
+    /// in global (desktop) coordinates.
+    ///
+    /// \param finger Finger index
+    /// \param relativeTo Reference window
+    ///
+    /// \return Current position of \a finger, or undefined if it's not down
+    ///
+    ////////////////////////////////////////////////////////////
+    static Vector2i getPosition(unsigned int finger, const Window& relativeTo);
+};
+
+} // namespace sf
+
+
+#endif // SFML_TOUCH_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Touch
+/// \ingroup window
+///
+/// sf::Touch provides an interface to the state of the
+/// touches. It only contains static functions, so it's not
+/// meant to be instantiated.
+///
+/// This class allows users to query the touches state at any
+/// time and directly, without having to deal with a window and
+/// its events. Compared to the TouchBegan, TouchMoved
+/// and TouchEnded events, sf::Touch can retrieve the
+/// state of the touches at any time (you don't need to store and
+/// update a boolean on your side in order to know if a touch is down),
+/// and you always get the real state of the touches, even if they
+/// happen when your window is out of focus and no event is triggered.
+///
+/// The getPosition function can be used to retrieve the current
+/// position of a touch. There are two versions: one that operates
+/// in global coordinates (relative to the desktop) and one that
+/// operates in window coordinates (relative to a specific window).
+///
+/// Touches are identified by an index (the "finger"), so that in
+/// multi-touch events, individual touches can be tracked correctly.
+/// As long as a finger touches the screen, it will keep the same index
+/// even if other fingers start or stop touching the screen in the
+/// meantime. As a consequence, active touch indices may not always be
+/// sequential (i.e. touch number 0 may be released while touch number 1
+/// is still down).
+///
+/// Usage example:
+/// \code
+/// if (sf::Touch::isDown(0))
+/// {
+///     // touch 0 is down
+/// }
+///
+/// // get global position of touch 1
+/// sf::Vector2i globalPos = sf::Touch::getPosition(1);
+///
+/// // get position of touch 1 relative to a window
+/// sf::Vector2i relativePos = sf::Touch::getPosition(1, window);
+/// \endcode
+///
+/// \see sf::Joystick, sf::Keyboard, sf::Mouse
+///
+////////////////////////////////////////////////////////////
index 5348833eaf7c7ba9bf7ba4f5f0a888dc6e328c2c..fcced93cc685b38c1a7337847c8b462764911308 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Config.hpp>
-#include <cstdlib>
+#include <SFML/Window/Export.hpp>
+#include <vector>
 
 
 namespace sf
 {
 ////////////////////////////////////////////////////////////
-/// VideoMode defines a video mode (width, height, bpp, frequency)
-/// and provides static functions for getting modes supported
-/// by the display device
+/// \brief VideoMode defines a video mode (width, height, bpp)
+///
 ////////////////////////////////////////////////////////////
-class SFML_API VideoMode
+class SFML_WINDOW_API VideoMode
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// This constructors initializes all members to 0.
     ///
     ////////////////////////////////////////////////////////////
     VideoMode();
 
     ////////////////////////////////////////////////////////////
-    /// Construct the video mode with its attributes
+    /// \brief Construct the video mode with its attributes
     ///
-    /// \param ModeWidth :  Width in pixels
-    /// \param ModeHeight : Height in pixels
-    /// \param ModeBpp :    Pixel depths in bits per pixel (32 by default)
+    /// \param modeWidth        Width in pixels
+    /// \param modeHeight       Height in pixels
+    /// \param modeBitsPerPixel Pixel depths in bits per pixel
     ///
     ////////////////////////////////////////////////////////////
-    VideoMode(unsigned int ModeWidth, unsigned int ModeHeight, unsigned int ModeBpp = 32);
+    VideoMode(unsigned int modeWidth, unsigned int modeHeight, unsigned int modeBitsPerPixel = 32);
 
     ////////////////////////////////////////////////////////////
-    /// Get the current desktop video mode
+    /// \brief Get the current desktop video mode
     ///
     /// \return Current desktop video mode
     ///
     ////////////////////////////////////////////////////////////
-    static VideoMode GetDesktopMode();
+    static VideoMode getDesktopMode();
 
     ////////////////////////////////////////////////////////////
-    /// Get a valid video mode
-    /// Index must be in range [0, GetModesCount()[
-    /// Modes are sorted from best to worst
+    /// \brief Retrieve all the video modes supported in fullscreen mode
     ///
-    /// \param Index : Index of video mode to get
+    /// When creating a fullscreen window, the video mode is restricted
+    /// to be compatible with what the graphics driver and monitor
+    /// support. This function returns the complete list of all video
+    /// modes that can be used in fullscreen mode.
+    /// The returned array is sorted from best to worst, so that
+    /// the first element will always give the best mode (higher
+    /// width, height and bits-per-pixel).
     ///
-    /// \return Corresponding video mode (invalid mode if index is out of range)
+    /// \return Array containing all the supported fullscreen modes
     ///
     ////////////////////////////////////////////////////////////
-    static VideoMode GetMode(std::size_t Index);
+    static const std::vector<VideoMode>& getFullscreenModes();
 
     ////////////////////////////////////////////////////////////
-    /// Get valid video modes count
-    ///
-    /// \return Number of valid video modes available
+    /// \brief Tell whether or not the video mode is valid
     ///
-    ////////////////////////////////////////////////////////////
-    static std::size_t GetModesCount();
-
-    ////////////////////////////////////////////////////////////
-    /// Tell whether or not the video mode is supported
+    /// The validity of video modes is only relevant when using
+    /// fullscreen windows; otherwise any video mode can be used
+    /// with no restriction.
     ///
-    /// \return True if video mode is supported, false otherwise
+    /// \return True if the video mode is valid for fullscreen mode
     ///
     ////////////////////////////////////////////////////////////
-    bool IsValid() const;
+    bool isValid() const;
 
     ////////////////////////////////////////////////////////////
-    /// Comparison operator overload -- tell if two video modes are equal
-    ///
-    /// \param Other : Video mode to compare
-    ///
-    /// \return True if modes are equal
-    ///
+    // Member data
     ////////////////////////////////////////////////////////////
-    bool operator ==(const VideoMode& Other) const;
+    unsigned int width;        ///< Video mode width, in pixels
+    unsigned int height;       ///< Video mode height, in pixels
+    unsigned int bitsPerPixel; ///< Video mode pixel depth, in bits per pixels
+};
 
-    ////////////////////////////////////////////////////////////
-    /// Comparison operator overload -- tell if two video modes are different
-    ///
-    /// \param Other : Video mode to compare
-    ///
-    /// \return True if modes are different
-    ///
-    ////////////////////////////////////////////////////////////
-    bool operator !=(const VideoMode& Other) const;
+////////////////////////////////////////////////////////////
+/// \relates VideoMode
+/// \brief Overload of == operator to compare two video modes
+///
+/// \param left  Left operand (a video mode)
+/// \param right Right operand (a video mode)
+///
+/// \return True if modes are equal
+///
+////////////////////////////////////////////////////////////
+SFML_WINDOW_API bool operator ==(const VideoMode& left, const VideoMode& right);
 
-    ////////////////////////////////////////////////////////////
-    // Member data
-    ////////////////////////////////////////////////////////////
-    unsigned int Width;        ///< Video mode width, in pixels
-    unsigned int Height;       ///< Video mode height, in pixels
-    unsigned int BitsPerPixel; ///< Video mode pixel depth, in bits per pixels
+////////////////////////////////////////////////////////////
+/// \relates VideoMode
+/// \brief Overload of != operator to compare two video modes
+///
+/// \param left  Left operand (a video mode)
+/// \param right Right operand (a video mode)
+///
+/// \return True if modes are different
+///
+////////////////////////////////////////////////////////////
+SFML_WINDOW_API bool operator !=(const VideoMode& left, const VideoMode& right);
 
-private :
+////////////////////////////////////////////////////////////
+/// \relates VideoMode
+/// \brief Overload of < operator to compare video modes
+///
+/// \param left  Left operand (a video mode)
+/// \param right Right operand (a video mode)
+///
+/// \return True if \a left is lesser than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_WINDOW_API bool operator <(const VideoMode& left, const VideoMode& right);
 
-    ////////////////////////////////////////////////////////////
-    /// Get and sort valid video modes
-    ////////////////////////////////////////////////////////////
-    static void InitializeModes();
-};
+////////////////////////////////////////////////////////////
+/// \relates VideoMode
+/// \brief Overload of > operator to compare video modes
+///
+/// \param left  Left operand (a video mode)
+/// \param right Right operand (a video mode)
+///
+/// \return True if \a left is greater than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_WINDOW_API bool operator >(const VideoMode& left, const VideoMode& right);
+
+////////////////////////////////////////////////////////////
+/// \relates VideoMode
+/// \brief Overload of <= operator to compare video modes
+///
+/// \param left  Left operand (a video mode)
+/// \param right Right operand (a video mode)
+///
+/// \return True if \a left is lesser or equal than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_WINDOW_API bool operator <=(const VideoMode& left, const VideoMode& right);
+
+////////////////////////////////////////////////////////////
+/// \relates VideoMode
+/// \brief Overload of >= operator to compare video modes
+///
+/// \param left  Left operand (a video mode)
+/// \param right Right operand (a video mode)
+///
+/// \return True if \a left is greater or equal than \a right
+///
+////////////////////////////////////////////////////////////
+SFML_WINDOW_API bool operator >=(const VideoMode& left, const VideoMode& right);
 
 } // namespace sf
 
 
 #endif // SFML_VIDEOMODE_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::VideoMode
+/// \ingroup window
+///
+/// A video mode is defined by a width and a height (in pixels)
+/// and a depth (in bits per pixel). Video modes are used to
+/// setup windows (sf::Window) at creation time.
+///
+/// The main usage of video modes is for fullscreen mode:
+/// indeed you must use one of the valid video modes
+/// allowed by the OS (which are defined by what the monitor
+/// and the graphics card support), otherwise your window
+/// creation will just fail.
+///
+/// sf::VideoMode provides a static function for retrieving
+/// the list of all the video modes supported by the system:
+/// getFullscreenModes().
+///
+/// A custom video mode can also be checked directly for
+/// fullscreen compatibility with its isValid() function.
+///
+/// Additionally, sf::VideoMode provides a static function
+/// to get the mode currently used by the desktop: getDesktopMode().
+/// This allows to build windows with the same size or pixel
+/// depth as the current resolution.
+///
+/// Usage example:
+/// \code
+/// // Display the list of all the video modes available for fullscreen
+/// std::vector<sf::VideoMode> modes = sf::VideoMode::getFullscreenModes();
+/// for (std::size_t i = 0; i < modes.size(); ++i)
+/// {
+///     sf::VideoMode mode = modes[i];
+///     std::cout << "Mode #" << i << ": "
+///               << mode.width << "x" << mode.height << " - "
+///               << mode.bitsPerPixel << " bpp" << std::endl;
+/// }
+///
+/// // Create a window with the same pixel depth as the desktop
+/// sf::VideoMode desktop = sf::VideoMode::getDesktopMode();
+/// window.create(sf::VideoMode(1024, 768, desktop.bitsPerPixel), "SFML window");
+/// \endcode
+///
+////////////////////////////////////////////////////////////
index 5e5628b3d53e61aa6edd2d922cdfc4d97498cb7d..88942dc44e1162fd822a465c9b747710f5ec4c73 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 // Headers
 ////////////////////////////////////////////////////////////
-#include <SFML/Window/Event.hpp>
-#include <SFML/Window/Input.hpp>
+#include <SFML/Window/Export.hpp>
+#include <SFML/Window/ContextSettings.hpp>
 #include <SFML/Window/VideoMode.hpp>
 #include <SFML/Window/WindowHandle.hpp>
-#include <SFML/Window/WindowListener.hpp>
-#include <SFML/Window/WindowSettings.hpp>
 #include <SFML/Window/WindowStyle.hpp>
+#include <SFML/Window/GlResource.hpp>
 #include <SFML/System/Clock.hpp>
+#include <SFML/System/Vector2.hpp>
 #include <SFML/System/NonCopyable.hpp>
-#include <queue>
-#include <string>
+#include <SFML/System/String.hpp>
 
 
 namespace sf
 {
 namespace priv
 {
+    class GlContext;
     class WindowImpl;
 }
 
+class Event;
+
 ////////////////////////////////////////////////////////////
-/// Window is a rendering window ; it can create a new window
-/// or connect to an existing one
+/// \brief Window that serves as a target for OpenGL rendering
+///
 ////////////////////////////////////////////////////////////
-class SFML_API Window : public WindowListener, NonCopyable
+class SFML_WINDOW_API Window : GlResource, NonCopyable
 {
-public :
+public:
 
     ////////////////////////////////////////////////////////////
-    /// Default constructor
+    /// \brief Default constructor
+    ///
+    /// This constructor doesn't actually create the window,
+    /// use the other constructors or call create() to do so.
     ///
     ////////////////////////////////////////////////////////////
     Window();
 
     ////////////////////////////////////////////////////////////
-    /// Construct a new window
+    /// \brief Construct a new window
+    ///
+    /// This constructor creates the window with the size and pixel
+    /// depth defined in \a mode. An optional style can be passed to
+    /// customize the look and behavior of the window (borders,
+    /// title bar, resizable, closable, ...). If \a style contains
+    /// Style::Fullscreen, then \a mode must be a valid video mode.
     ///
-    /// \param Mode :        Video mode to use
-    /// \param Title :       Title of the window
-    /// \param WindowStyle : Window style, see sf::Style (Resize | Close by default)
-    /// \param Params :      Creation parameters (see default constructor for default values)
+    /// The fourth parameter is an optional structure specifying
+    /// advanced OpenGL context settings such as antialiasing,
+    /// depth-buffer bits, etc.
+    ///
+    /// \param mode     Video mode to use (defines the width, height and depth of the rendering area of the window)
+    /// \param title    Title of the window
+    /// \param style    %Window style, a bitwise OR combination of sf::Style enumerators
+    /// \param settings Additional settings for the underlying OpenGL context
     ///
     ////////////////////////////////////////////////////////////
-    Window(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings());
+    Window(VideoMode mode, const String& title, Uint32 style = Style::Default, const ContextSettings& settings = ContextSettings());
 
     ////////////////////////////////////////////////////////////
-    /// Construct the window from an existing control
+    /// \brief Construct the window from an existing control
+    ///
+    /// Use this constructor if you want to create an OpenGL
+    /// rendering area into an already existing control.
     ///
-    /// \param Handle : Platform-specific handle of the control
-    /// \param Params : Creation parameters (see default constructor for default values)
+    /// The second parameter is an optional structure specifying
+    /// advanced OpenGL context settings such as antialiasing,
+    /// depth-buffer bits, etc.
+    ///
+    /// \param handle   Platform-specific handle of the control (\a HWND on
+    ///                 Windows, \a %Window on Linux/FreeBSD, \a NSWindow on OS X)
+    /// \param settings Additional settings for the underlying OpenGL context
     ///
     ////////////////////////////////////////////////////////////
-    Window(WindowHandle Handle, const WindowSettings& Params = WindowSettings());
+    explicit Window(WindowHandle handle, const ContextSettings& settings = ContextSettings());
 
     ////////////////////////////////////////////////////////////
-    /// Destructor
+    /// \brief Destructor
+    ///
+    /// Closes the window and frees all the resources attached to it.
     ///
     ////////////////////////////////////////////////////////////
     virtual ~Window();
 
     ////////////////////////////////////////////////////////////
-    /// Create (or recreate) the window
+    /// \brief Create (or recreate) the window
+    ///
+    /// If the window was already created, it closes it first.
+    /// If \a style contains Style::Fullscreen, then \a mode
+    /// must be a valid video mode.
+    ///
+    /// The fourth parameter is an optional structure specifying
+    /// advanced OpenGL context settings such as antialiasing,
+    /// depth-buffer bits, etc.
     ///
-    /// \param Mode :        Video mode to use
-    /// \param Title :       Title of the window
-    /// \param WindowStyle : Window style, see sf::Style (Resize | Close by default)
-    /// \param Params :      Creation parameters (see default constructor for default values)
+    /// \param mode     Video mode to use (defines the width, height and depth of the rendering area of the window)
+    /// \param title    Title of the window
+    /// \param style    %Window style, a bitwise OR combination of sf::Style enumerators
+    /// \param settings Additional settings for the underlying OpenGL context
     ///
     ////////////////////////////////////////////////////////////
-    void Create(VideoMode Mode, const std::string& Title, unsigned long WindowStyle = Style::Resize | Style::Close, const WindowSettings& Params = WindowSettings());
+    void create(VideoMode mode, const String& title, Uint32 style = Style::Default, const ContextSettings& settings = ContextSettings());
 
     ////////////////////////////////////////////////////////////
-    /// Create (or recreate) the window from an existing control
+    /// \brief Create (or recreate) the window from an existing control
     ///
-    /// \param Handle : Platform-specific handle of the control
-    /// \param Params : Creation parameters (see default constructor for default values)
+    /// Use this function if you want to create an OpenGL
+    /// rendering area into an already existing control.
+    /// If the window was already created, it closes it first.
+    ///
+    /// The second parameter is an optional structure specifying
+    /// advanced OpenGL context settings such as antialiasing,
+    /// depth-buffer bits, etc.
+    ///
+    /// \param handle   Platform-specific handle of the control (\a HWND on
+    ///                 Windows, \a %Window on Linux/FreeBSD, \a NSWindow on OS X)
+    /// \param settings Additional settings for the underlying OpenGL context
     ///
     ////////////////////////////////////////////////////////////
-    void Create(WindowHandle Handle, const WindowSettings& Params = WindowSettings());
+    void create(WindowHandle handle, const ContextSettings& settings = ContextSettings());
 
     ////////////////////////////////////////////////////////////
-    /// Close (destroy) the window.
-    /// The sf::Window instance remains valid and you can call
-    /// Create to recreate the window
+    /// \brief Close the window and destroy all the attached resources
+    ///
+    /// After calling this function, the sf::Window instance remains
+    /// valid and you can call create() to recreate the window.
+    /// All other functions such as pollEvent() or display() will
+    /// still work (i.e. you don't have to test isOpen() every time),
+    /// and will have no effect on closed windows.
     ///
     ////////////////////////////////////////////////////////////
-    void Close();
+    void close();
 
     ////////////////////////////////////////////////////////////
-    /// Tell whether or not the window is opened (ie. has been created).
-    /// Note that a hidden window (Show(false))
-    /// will still return true
+    /// \brief Tell whether or not the window is open
+    ///
+    /// This function returns whether or not the window exists.
+    /// Note that a hidden window (setVisible(false)) is open
+    /// (therefore this function would return true).
     ///
-    /// \return True if the window is opened
+    /// \return True if the window is open, false if it has been closed
     ///
     ////////////////////////////////////////////////////////////
-    bool IsOpened() const;
+    bool isOpen() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the width of the rendering region of the window
+    /// \brief Get the settings of the OpenGL context of the window
     ///
-    /// \return Width in pixels
+    /// Note that these settings may be different from what was
+    /// passed to the constructor or the create() function,
+    /// if one or more settings were not supported. In this case,
+    /// SFML chose the closest match.
+    ///
+    /// \return Structure containing the OpenGL context settings
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetWidth() const;
+    const ContextSettings& getSettings() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the height of the rendering region of the window
+    /// \brief Pop the event on top of the event queue, if any, and return it
+    ///
+    /// This function is not blocking: if there's no pending event then
+    /// it will return false and leave \a event unmodified.
+    /// Note that more than one event may be present in the event queue,
+    /// thus you should always call this function in a loop
+    /// to make sure that you process every pending event.
+    /// \code
+    /// sf::Event event;
+    /// while (window.pollEvent(event))
+    /// {
+    ///    // process event...
+    /// }
+    /// \endcode
+    ///
+    /// \param event Event to be returned
+    ///
+    /// \return True if an event was returned, or false if the event queue was empty
     ///
-    /// \return Height in pixels
+    /// \see waitEvent
     ///
     ////////////////////////////////////////////////////////////
-    unsigned int GetHeight() const;
+    bool pollEvent(Event& event);
 
     ////////////////////////////////////////////////////////////
-    /// Get the creation settings of the window
+    /// \brief Wait for an event and return it
+    ///
+    /// This function is blocking: if there's no pending event then
+    /// it will wait until an event is received.
+    /// After this function returns (and no error occurred),
+    /// the \a event object is always valid and filled properly.
+    /// This function is typically used when you have a thread that
+    /// is dedicated to events handling: you want to make this thread
+    /// sleep as long as no new event is received.
+    /// \code
+    /// sf::Event event;
+    /// if (window.waitEvent(event))
+    /// {
+    ///    // process event...
+    /// }
+    /// \endcode
+    ///
+    /// \param event Event to be returned
+    ///
+    /// \return False if any error occurred
+    ///
+    /// \see pollEvent
+    ///
+    ////////////////////////////////////////////////////////////
+    bool waitEvent(Event& event);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Get the position of the window
+    ///
+    /// \return Position of the window, in pixels
+    ///
+    /// \see setPosition
+    ///
+    ////////////////////////////////////////////////////////////
+    Vector2i getPosition() const;
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Change the position of the window on screen
+    ///
+    /// This function only works for top-level windows
+    /// (i.e. it will be ignored for windows created from
+    /// the handle of a child window/control).
+    ///
+    /// \param position New position, in pixels
     ///
-    /// \return Structure containing the creation settings
+    /// \see getPosition
     ///
     ////////////////////////////////////////////////////////////
-    const WindowSettings& GetSettings() const;
+    void setPosition(const Vector2i& position);
 
     ////////////////////////////////////////////////////////////
-    /// Get the event on top of events stack, if any, and pop it
+    /// \brief Get the size of the rendering region of the window
     ///
-    /// \param EventReceived : Event to fill, if any
+    /// The size doesn't include the titlebar and borders
+    /// of the window.
     ///
-    /// \return True if an event was returned, false if events stack was empty
+    /// \return Size in pixels
+    ///
+    /// \see setSize
     ///
     ////////////////////////////////////////////////////////////
-    bool GetEvent(Event& EventReceived);
+    Vector2u getSize() const;
 
     ////////////////////////////////////////////////////////////
-    /// Enable / disable vertical synchronization
+    /// \brief Change the size of the rendering region of the window
+    ///
+    /// \param size New size, in pixels
     ///
-    /// \param Enabled : True to enable v-sync, false to deactivate
+    /// \see getSize
     ///
     ////////////////////////////////////////////////////////////
-    void UseVerticalSync(bool Enabled);
+    void setSize(const Vector2u& size);
 
     ////////////////////////////////////////////////////////////
-    /// Show or hide the mouse cursor
+    /// \brief Change the title of the window
+    ///
+    /// \param title New title
     ///
-    /// \param Show : True to show, false to hide
+    /// \see setIcon
     ///
     ////////////////////////////////////////////////////////////
-    void ShowMouseCursor(bool Show);
+    void setTitle(const String& title);
 
     ////////////////////////////////////////////////////////////
-    /// Change the position of the mouse cursor
+    /// \brief Change the window's icon
+    ///
+    /// \a pixels must be an array of \a width x \a height pixels
+    /// in 32-bits RGBA format.
+    ///
+    /// The OS default icon is used by default.
     ///
-    /// \param Left : Left coordinate of the cursor, relative to the window
-    /// \param Top :  Top coordinate of the cursor, relative to the window
+    /// \param width  Icon's width, in pixels
+    /// \param height Icon's height, in pixels
+    /// \param pixels Pointer to the array of pixels in memory. The
+    ///               pixels are copied, so you need not keep the
+    ///               source alive after calling this function.
+    ///
+    /// \see setTitle
     ///
     ////////////////////////////////////////////////////////////
-    void SetCursorPosition(unsigned int Left, unsigned int Top);
+    void setIcon(unsigned int width, unsigned int height, const Uint8* pixels);
 
     ////////////////////////////////////////////////////////////
-    /// Change the position of the window on screen.
-    /// Only works for top-level windows
+    /// \brief Show or hide the window
+    ///
+    /// The window is shown by default.
     ///
-    /// \param Left : Left position
-    /// \param Top :  Top position
+    /// \param visible True to show the window, false to hide it
     ///
     ////////////////////////////////////////////////////////////
-    void SetPosition(int Left, int Top);
+    void setVisible(bool visible);
 
     ////////////////////////////////////////////////////////////
-    /// Change the size of the rendering region of the window
+    /// \brief Enable or disable vertical synchronization
+    ///
+    /// Activating vertical synchronization will limit the number
+    /// of frames displayed to the refresh rate of the monitor.
+    /// This can avoid some visual artifacts, and limit the framerate
+    /// to a good value (but not constant across different computers).
+    ///
+    /// Vertical synchronization is disabled by default.
     ///
-    /// \param Width :  New width
-    /// \param Height : New height
+    /// \param enabled True to enable v-sync, false to deactivate it
     ///
     ////////////////////////////////////////////////////////////
-    void SetSize(unsigned int Width, unsigned int Height);
+    void setVerticalSyncEnabled(bool enabled);
 
     ////////////////////////////////////////////////////////////
-    /// Show or hide the window
+    /// \brief Show or hide the mouse cursor
     ///
-    /// \param State : True to show, false to hide
+    /// The mouse cursor is visible by default.
+    ///
+    /// \param visible True to show the mouse cursor, false to hide it
     ///
     ////////////////////////////////////////////////////////////
-    void Show(bool State);
+    void setMouseCursorVisible(bool visible);
 
     ////////////////////////////////////////////////////////////
-    /// Enable or disable automatic key-repeat.
-    /// Automatic key-repeat is enabled by default
+    /// \brief Enable or disable automatic key-repeat
+    ///
+    /// If key repeat is enabled, you will receive repeated
+    /// KeyPressed events while keeping a key pressed. If it is disabled,
+    /// you will only get a single event when the key is pressed.
     ///
-    /// \param Enabled : True to enable, false to disable
+    /// Key repeat is enabled by default.
+    ///
+    /// \param enabled True to enable, false to disable
     ///
     ////////////////////////////////////////////////////////////
-    void EnableKeyRepeat(bool Enabled);
+    void setKeyRepeatEnabled(bool enabled);
 
     ////////////////////////////////////////////////////////////
-    /// Change the window's icon
+    /// \brief Limit the framerate to a maximum fixed frequency
+    ///
+    /// If a limit is set, the window will use a small delay after
+    /// each call to display() to ensure that the current frame
+    /// lasted long enough to match the framerate limit.
+    /// SFML will try to match the given limit as much as it can,
+    /// but since it internally uses sf::sleep, whose precision
+    /// depends on the underlying OS, the results may be a little
+    /// unprecise as well (for example, you can get 65 FPS when
+    /// requesting 60).
     ///
-    /// \param Width :  Icon's width, in pixels
-    /// \param Height : Icon's height, in pixels
-    /// \param Pixels : Pointer to the pixels in memory, format must be RGBA 32 bits
+    /// \param limit Framerate limit, in frames per seconds (use 0 to disable limit)
     ///
     ////////////////////////////////////////////////////////////
-    void SetIcon(unsigned int Width, unsigned int Height, const Uint8* Pixels);
+    void setFramerateLimit(unsigned int limit);
 
     ////////////////////////////////////////////////////////////
-    /// Activate of deactivate the window as the current target
-    /// for rendering
+    /// \brief Change the joystick threshold
     ///
-    /// \param Active : True to activate, false to deactivate (true by default)
+    /// The joystick threshold is the value below which
+    /// no JoystickMoved event will be generated.
     ///
-    /// \return True if operation was successful, false otherwise
+    /// The threshold value is 0.1 by default.
+    ///
+    /// \param threshold New threshold, in the range [0, 100]
     ///
     ////////////////////////////////////////////////////////////
-    bool SetActive(bool Active = true) const;
+    void setJoystickThreshold(float threshold);
 
     ////////////////////////////////////////////////////////////
-    /// Display the window on screen
+    /// \brief Activate or deactivate the window as the current target
+    ///        for OpenGL rendering
+    ///
+    /// A window is active only on the current thread, if you want to
+    /// make it active on another thread you have to deactivate it
+    /// on the previous thread first if it was active.
+    /// Only one window can be active on a thread at a time, thus
+    /// the window previously active (if any) automatically gets deactivated.
+    /// This is not to be confused with requestFocus().
+    ///
+    /// \param active True to activate, false to deactivate
+    ///
+    /// \return True if operation was successful, false otherwise
     ///
     ////////////////////////////////////////////////////////////
-    void Display();
+    bool setActive(bool active = true) const;
 
     ////////////////////////////////////////////////////////////
-    /// Get the input manager of the window
+    /// \brief Request the current window to be made the active
+    ///        foreground window
     ///
-    /// \return Reference to the input
+    /// At any given time, only one window may have the input focus
+    /// to receive input events such as keystrokes or mouse events.
+    /// If a window requests focus, it only hints to the operating
+    /// system, that it would like to be focused. The operating system
+    /// is free to deny the request.
+    /// This is not to be confused with setActive().
+    ///
+    /// \see hasFocus
     ///
     ////////////////////////////////////////////////////////////
-    const Input& GetInput() const;
+    void requestFocus();
 
     ////////////////////////////////////////////////////////////
-    /// Limit the framerate to a maximum fixed frequency
+    /// \brief Check whether the window has the input focus
+    ///
+    /// At any given time, only one window may have the input focus
+    /// to receive input events such as keystrokes or most mouse
+    /// events.
     ///
-    /// \param Limit : Framerate limit, in frames per seconds (use 0 to disable limit)
+    /// \return True if window has focus, false otherwise
+    /// \see requestFocus
     ///
     ////////////////////////////////////////////////////////////
-    void SetFramerateLimit(unsigned int Limit);
+    bool hasFocus() const;
 
     ////////////////////////////////////////////////////////////
-    /// Get time elapsed since last frame
+    /// \brief Display on screen what has been rendered to the window so far
     ///
-    /// \return Time elapsed, in seconds
+    /// This function is typically called after all OpenGL rendering
+    /// has been done for the current frame, in order to show
+    /// it on screen.
     ///
     ////////////////////////////////////////////////////////////
-    float GetFrameTime() const;
+    void display();
 
     ////////////////////////////////////////////////////////////
-    /// Change the joystick threshold, ie. the value below which
-    /// no move event will be generated
+    /// \brief Get the OS-specific handle of the window
     ///
-    /// \param Threshold : New threshold, in range [0, 100]
+    /// The type of the returned handle is sf::WindowHandle,
+    /// which is a typedef to the handle type defined by the OS.
+    /// You shouldn't need to use this function, unless you have
+    /// very specific stuff to implement that SFML doesn't support,
+    /// or implement a temporary workaround until a bug is fixed.
+    /// The type is \a HWND on Windows, \a %Window on Linux/FreeBSD
+    /// and \a NSWindow on OS X.
+    ///
+    /// \return System handle of the window
     ///
     ////////////////////////////////////////////////////////////
-    void SetJoystickThreshold(float Threshold);
+    WindowHandle getSystemHandle() const;
 
-private :
+protected:
 
     ////////////////////////////////////////////////////////////
-    /// Called after the window has been created
+    /// \brief Function called after the window has been created
+    ///
+    /// This function is called so that derived classes can
+    /// perform their own specific initialization as soon as
+    /// the window is created.
     ///
     ////////////////////////////////////////////////////////////
-    virtual void OnCreate();
+    virtual void onCreate();
 
     ////////////////////////////////////////////////////////////
-    /// /see WindowListener::OnEvent
+    /// \brief Function called after the window has been resized
     ///
-    /// \param EventReceived : Event received
+    /// This function is called so that derived classes can
+    /// perform custom actions when the size of the window changes.
     ///
     ////////////////////////////////////////////////////////////
-    virtual void OnEvent(const Event& EventReceived);
+    virtual void onResize();
+
+private:
 
     ////////////////////////////////////////////////////////////
-    /// Initialize internal window
+    /// \brief Processes an event before it is sent to the user
+    ///
+    /// This function is called every time an event is received
+    /// from the internal window (through pollEvent or waitEvent).
+    /// It filters out unwanted events, and performs whatever internal
+    /// stuff the window needs before the event is returned to the
+    /// user.
     ///
-    /// \param Impl : New internal window implementation
+    /// \param event Event to filter
     ///
     ////////////////////////////////////////////////////////////
-    void Initialize(priv::WindowImpl* Impl);
+    bool filterEvent(const Event& event);
+
+    ////////////////////////////////////////////////////////////
+    /// \brief Perform some common internal initializations
+    ///
+    ////////////////////////////////////////////////////////////
+    void initialize();
 
     ////////////////////////////////////////////////////////////
     // Member data
     ////////////////////////////////////////////////////////////
-    priv::WindowImpl* myWindow;         ///< Platform-specific implementation of window
-    std::queue<Event> myEvents;         ///< Queue of received events
-    Input             myInput;          ///< Input manager connected to window
-    Clock             myClock;          ///< Clock for measuring the elapsed time between frames
-    WindowSettings    mySettings;       ///< Creation settings of the window
-    float             myLastFrameTime;  ///< Time elapsed since last frame
-    bool              myIsExternal;     ///< Tell whether the window is internal or external (created by SFML or not)
-    unsigned int      myFramerateLimit; ///< Current framerate limit
-    int               mySetCursorPosX;  ///< X coordinate passed to the last call to SetCursorPosition
-    int               mySetCursorPosY;  ///< Y coordinate passed to the last call to SetCursorPosition
+    priv::WindowImpl* m_impl;           ///< Platform-specific implementation of the window
+    priv::GlContext*  m_context;        ///< Platform-specific implementation of the OpenGL context
+    Clock             m_clock;          ///< Clock for measuring the elapsed time between frames
+    Time              m_frameTimeLimit; ///< Current framerate limit
+    Vector2u          m_size;           ///< Current size of the window
 };
 
 } // namespace sf
 
 
 #endif // SFML_WINDOW_HPP
+
+
+////////////////////////////////////////////////////////////
+/// \class sf::Window
+/// \ingroup window
+///
+/// sf::Window is the main class of the Window module. It defines
+/// an OS window that is able to receive an OpenGL rendering.
+///
+/// A sf::Window can create its own new window, or be embedded into
+/// an already existing control using the create(handle) function.
+/// This can be useful for embedding an OpenGL rendering area into
+/// a view which is part of a bigger GUI with existing windows,
+/// controls, etc. It can also serve as embedding an OpenGL rendering
+/// area into a window created by another (probably richer) GUI library
+/// like Qt or wxWidgets.
+///
+/// The sf::Window class provides a simple interface for manipulating
+/// the window: move, resize, show/hide, control mouse cursor, etc.
+/// It also provides event handling through its pollEvent() and waitEvent()
+/// functions.
+///
+/// Note that OpenGL experts can pass their own parameters (antialiasing
+/// level, bits for the depth and stencil buffers, etc.) to the
+/// OpenGL context attached to the window, with the sf::ContextSettings
+/// structure which is passed as an optional argument when creating the
+/// window.
+///
+/// Usage example:
+/// \code
+/// // Declare and create a new window
+/// sf::Window window(sf::VideoMode(800, 600), "SFML window");
+///
+/// // Limit the framerate to 60 frames per second (this step is optional)
+/// window.setFramerateLimit(60);
+///
+/// // The main loop - ends as soon as the window is closed
+/// while (window.isOpen())
+/// {
+///    // Event processing
+///    sf::Event event;
+///    while (window.pollEvent(event))
+///    {
+///        // Request for closing the window
+///        if (event.type == sf::Event::Closed)
+///            window.close();
+///    }
+///
+///    // Activate the window for OpenGL rendering
+///    window.setActive();
+///
+///    // OpenGL drawing commands go here...
+///
+///    // End the current frame and display its contents on screen
+///    window.display();
+/// }
+/// \endcode
+///
+////////////////////////////////////////////////////////////
index 852036c00854c7acbf4d712586643af069518804..b7c67a5b4318165835ab300f4a98cd9fe20057f0 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 ////////////////////////////////////////////////////////////
 #include <SFML/Config.hpp>
 
+// Windows' HWND is a typedef on struct HWND__*
+#if defined(SFML_SYSTEM_WINDOWS)
+    struct HWND__;
+#endif
 
 namespace sf
 {
@@ -39,18 +43,28 @@ namespace sf
 ////////////////////////////////////////////////////////////
 #if defined(SFML_SYSTEM_WINDOWS)
 
-    // Windows defines a void* handle (HWND)
-    typedef void* WindowHandle;
+    // Window handle is HWND (HWND__*) on Windows
+    typedef HWND__* WindowHandle;
 
 #elif defined(SFML_SYSTEM_LINUX) || defined(SFML_SYSTEM_FREEBSD)
 
-    // Unix - X11 defines an unsigned integer handle (Window)
+    // Window handle is Window (unsigned long) on Unix - X11
     typedef unsigned long WindowHandle;
 
 #elif defined(SFML_SYSTEM_MACOS)
 
-    // Mac OS X defines a void* handle (NSWindow)
-       typedef void* WindowHandle;
+    // Window handle is NSWindow (void*) on Mac OS X - Cocoa
+    typedef void* WindowHandle;
+
+#elif defined(SFML_SYSTEM_IOS)
+
+    // Window handle is UIWindow (void*) on iOS - UIKit
+    typedef void* WindowHandle;
+
+#elif defined(SFML_SYSTEM_ANDROID)
+
+    // Window handle is ANativeWindow (void*) on Android
+    typedef void* WindowHandle;
 
 #endif
 
index 9649453ae9335e0d571c05f2f8e27e0be5a139f1..cd721b3b0d8b6ff8ead31ac6ade10c3f7fcedf12 100644 (file)
@@ -1,7 +1,7 @@
 ////////////////////////////////////////////////////////////
 //
 // SFML - Simple and Fast Multimedia Library
-// Copyright (C) 2007-2009 Laurent Gomila (laurent.gom@gmail.com)
+// Copyright (C) 2007-2014 Laurent Gomila (laurent.gom@gmail.com)
 //
 // This software is provided 'as-is', without any express or implied warranty.
 // In no event will the authors be held liable for any damages arising from the use of this software.
 
 namespace sf
 {
-
-////////////////////////////////////////////////////////////
-/// Enumeration of window creation styles
-////////////////////////////////////////////////////////////
 namespace Style
 {
+    ////////////////////////////////////////////////////////////
+    /// \ingroup window
+    /// \brief Enumeration of the window styles
+    ///
+    ////////////////////////////////////////////////////////////
     enum
     {
         None       = 0,      ///< No border / title bar (this flag and all others are mutually exclusive)
         Titlebar   = 1 << 0, ///< Title bar + fixed border
-        Resize     = 1 << 1, ///< Titlebar + resizable border + maximize button
-        Close      = 1 << 2, ///< Titlebar + close button
-        Fullscreen = 1 << 3  ///< Fullscreen mode (this flag and all others are mutually exclusive)
+        Resize     = 1 << 1, ///< Title bar + resizable border + maximize button
+        Close      = 1 << 2, ///< Title bar + close button
+        Fullscreen = 1 << 3, ///< Fullscreen mode (this flag and all others are mutually exclusive)
+
+        Default = Titlebar | Resize | Close ///< Default window style
     };
 }
 
-
 } // namespace sf
 
 
diff --git a/dependencies64/sfml/lib/sfml-audio-2.lib b/dependencies64/sfml/lib/sfml-audio-2.lib
new file mode 100644 (file)
index 0000000..cd462bf
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-audio-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-audio-d-2.lib b/dependencies64/sfml/lib/sfml-audio-d-2.lib
new file mode 100644 (file)
index 0000000..05661fd
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-audio-d-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-audio-d.lib b/dependencies64/sfml/lib/sfml-audio-d.lib
deleted file mode 100644 (file)
index 3d19a71..0000000
Binary files a/dependencies64/sfml/lib/sfml-audio-d.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-audio.lib b/dependencies64/sfml/lib/sfml-audio.lib
deleted file mode 100644 (file)
index 1bb09b0..0000000
Binary files a/dependencies64/sfml/lib/sfml-audio.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-graphics-2.lib b/dependencies64/sfml/lib/sfml-graphics-2.lib
new file mode 100644 (file)
index 0000000..b6f5b21
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-graphics-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-graphics-d-2.lib b/dependencies64/sfml/lib/sfml-graphics-d-2.lib
new file mode 100644 (file)
index 0000000..1397e55
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-graphics-d-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-graphics-d.lib b/dependencies64/sfml/lib/sfml-graphics-d.lib
deleted file mode 100644 (file)
index a0b5853..0000000
Binary files a/dependencies64/sfml/lib/sfml-graphics-d.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-graphics.lib b/dependencies64/sfml/lib/sfml-graphics.lib
deleted file mode 100644 (file)
index 7daf033..0000000
Binary files a/dependencies64/sfml/lib/sfml-graphics.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-system-2.lib b/dependencies64/sfml/lib/sfml-system-2.lib
new file mode 100644 (file)
index 0000000..3b4ca91
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-system-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-system-d-2.lib b/dependencies64/sfml/lib/sfml-system-d-2.lib
new file mode 100644 (file)
index 0000000..1bbea29
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-system-d-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-system-d.lib b/dependencies64/sfml/lib/sfml-system-d.lib
deleted file mode 100644 (file)
index 86f1ea4..0000000
Binary files a/dependencies64/sfml/lib/sfml-system-d.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-system.lib b/dependencies64/sfml/lib/sfml-system.lib
deleted file mode 100644 (file)
index e7d6ebb..0000000
Binary files a/dependencies64/sfml/lib/sfml-system.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-window-2.lib b/dependencies64/sfml/lib/sfml-window-2.lib
new file mode 100644 (file)
index 0000000..b75c3b8
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-window-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-window-d-2.lib b/dependencies64/sfml/lib/sfml-window-d-2.lib
new file mode 100644 (file)
index 0000000..d9bc34b
Binary files /dev/null and b/dependencies64/sfml/lib/sfml-window-d-2.lib differ
diff --git a/dependencies64/sfml/lib/sfml-window-d.lib b/dependencies64/sfml/lib/sfml-window-d.lib
deleted file mode 100644 (file)
index 47d6f30..0000000
Binary files a/dependencies64/sfml/lib/sfml-window-d.lib and /dev/null differ
diff --git a/dependencies64/sfml/lib/sfml-window.lib b/dependencies64/sfml/lib/sfml-window.lib
deleted file mode 100644 (file)
index 224c9b2..0000000
Binary files a/dependencies64/sfml/lib/sfml-window.lib and /dev/null differ
index 1b0f2b789b86d77f053c11a4fd3ebbbaa850f950..a1abe1ee824ba281d7f8657df572f88d58bea732 100644 (file)
Binary files a/dependencies64/tbb/bin/tbb.dll and b/dependencies64/tbb/bin/tbb.dll differ
index f2cc8d3ee2909917657d4131b10560b298772010..6446fefd9527cd871d173fff3b88d22dec075a11 100644 (file)
Binary files a/dependencies64/tbb/bin/tbb.pdb and b/dependencies64/tbb/bin/tbb.pdb differ
index 5b624883a60e2abb5d408d2f526ee3ee2fafe4c9..920e3de1eb0fba958b175c5942b61c9328abb28c 100644 (file)
Binary files a/dependencies64/tbb/bin/tbb_debug.dll and b/dependencies64/tbb/bin/tbb_debug.dll differ
index 341a1a6d7068b44b910b95dddd4d9f69e6ac8431..9e2d8db88e1e310cc9ce6f3930f36d05328e3d2d 100644 (file)
Binary files a/dependencies64/tbb/bin/tbb_debug.pdb and b/dependencies64/tbb/bin/tbb_debug.pdb differ
diff --git a/dependencies64/tbb/bin/tbb_preview.dll b/dependencies64/tbb/bin/tbb_preview.dll
new file mode 100644 (file)
index 0000000..c82b3cb
Binary files /dev/null and b/dependencies64/tbb/bin/tbb_preview.dll differ
diff --git a/dependencies64/tbb/bin/tbb_preview.pdb b/dependencies64/tbb/bin/tbb_preview.pdb
new file mode 100644 (file)
index 0000000..2e258a9
Binary files /dev/null and b/dependencies64/tbb/bin/tbb_preview.pdb differ
diff --git a/dependencies64/tbb/bin/tbb_preview_debug.dll b/dependencies64/tbb/bin/tbb_preview_debug.dll
new file mode 100644 (file)
index 0000000..77a2af7
Binary files /dev/null and b/dependencies64/tbb/bin/tbb_preview_debug.dll differ
diff --git a/dependencies64/tbb/bin/tbb_preview_debug.pdb b/dependencies64/tbb/bin/tbb_preview_debug.pdb
new file mode 100644 (file)
index 0000000..f2277b0
Binary files /dev/null and b/dependencies64/tbb/bin/tbb_preview_debug.pdb differ
index 79414a34f7159372e77f34904cf13af092e0365f..aa3e291560a01454bf0e0d18898cb8063a270614 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc.dll and b/dependencies64/tbb/bin/tbbmalloc.dll differ
index 99a8b83b50885c9d4082b7dd0c537452b63257b6..8cb385c548e1cf4949770fc9e45924fb3cc690a9 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc.pdb and b/dependencies64/tbb/bin/tbbmalloc.pdb differ
index 2e025c84fe4fb5f738101182c792479cfc577365..0cfece1ee0dba31560ad91db71c548f74f72ae65 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc_debug.dll and b/dependencies64/tbb/bin/tbbmalloc_debug.dll differ
index 7b938d7381bf81e8b7b1fe7d414ac418c4e9185a..1cee81918a3fcd31e5d2100331b629f9e5cfa67f 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc_debug.pdb and b/dependencies64/tbb/bin/tbbmalloc_debug.pdb differ
index 0320fcb4cfc5d29dcc5205602f9c3e06db32e71d..68842a657269ffbae68832aaac350f4dad2a2c05 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc_proxy.dll and b/dependencies64/tbb/bin/tbbmalloc_proxy.dll differ
index ba3de6ff26ea8a038acb1e01581311db6b1bdf80..e827e16d1d12353794d0cab7810b4ab4860a6f99 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc_proxy.pdb and b/dependencies64/tbb/bin/tbbmalloc_proxy.pdb differ
index 1812c85345cf2740dc08fea31bd4a2b1b6ff63f7..fe79a82833619bb09edb8cf06091a2783f839f1d 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc_proxy_debug.dll and b/dependencies64/tbb/bin/tbbmalloc_proxy_debug.dll differ
index 257d82ad99c0d21975c4e0398d1af5e1204390e5..987658252c9b4fb9aed6eaf1b336e17abb5434eb 100644 (file)
Binary files a/dependencies64/tbb/bin/tbbmalloc_proxy_debug.pdb and b/dependencies64/tbb/bin/tbbmalloc_proxy_debug.pdb differ
index ee0848939e852f716bc82b8b271b4e23cf9a17e8..0c85b47f82a5c0901d1053c8565962f3b05d3a1b 100644 (file)
@@ -2,18 +2,18 @@
 <BODY>
 
 <H2>Overview</H2>
-Include files for Threading Building Blocks.
+Include files for Intel&reg; Threading Building Blocks (Intel&reg; TBB).
 
 <H2>Directories</H2>
 <DL>
 <DT><A HREF="tbb/index.html">tbb</A>
-<DD>Include files for Threading Building Blocks classes and functions.
+<DD>Include files for Intel TBB classes and functions.
 </DL>
 
 <HR>
 <A HREF="../index.html">Up to parent directory</A>
 <p></p>
-Copyright &copy; 2005-2011 Intel Corporation.  All Rights Reserved.
+Copyright &copy; 2005-2014 Intel Corporation.  All Rights Reserved.
 <P></P>
 Intel is a registered trademark or trademark of Intel Corporation
 or its subsidiaries in the United States and other countries.
index e953cf071a3bb71c304976b8fc272491736d3c1b..e0bddb713b7f0b921f2da336835526a65a257e90 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_SERIAL_parallel_for_H
@@ -51,7 +43,7 @@
 
 namespace tbb {
 namespace serial {
-namespace interface6 {
+namespace interface7 {
 
 // parallel_for serial annotated implementation
 
@@ -72,19 +64,19 @@ class start_for : tbb::internal::no_copy {
 
     //! Splitting constructor used to generate children.
     /** this becomes left child.  Newly constructed object is right child. */
-    start_for( start_for& parent_, split ) :
-        my_range( parent_.my_range, split() ),
+    start_for( start_for& parent_, typename Partitioner::split_type& split_obj ) :
+        my_range( parent_.my_range, split_obj ),
         my_body( parent_.my_body ),
-        my_partition( parent_.my_partition, split() )
+        my_partition( parent_.my_partition, split_obj )
     {
     }
 
 public:
-    static void run(  const Range& range, const Body& body, const Partitioner& partitioner ) {
+    static void run(  const Range& range, const Body& body, Partitioner& partitioner ) {
         if( !range.empty() ) {
             ANNOTATE_SITE_BEGIN( tbb_parallel_for );
             {
-                start_for a( range, body, const_cast< Partitioner& >( partitioner ) );
+                start_for a( range, body, partitioner );
                 a.execute();
             }
             ANNOTATE_SITE_END( tbb_parallel_for );
@@ -94,50 +86,51 @@ public:
 
 template< typename Range, typename Body, typename Partitioner >
 void start_for< Range, Body, Partitioner >::execute() {
-    if( !my_range.is_divisible() || !my_partition.divisions_left() ) {
+    if( !my_range.is_divisible() || !my_partition.is_divisible() ) {
         ANNOTATE_TASK_BEGIN( tbb_parallel_for_range );
         {
             my_body( my_range );
         }
         ANNOTATE_TASK_END( tbb_parallel_for_range );
     } else {
-        start_for b( *this, split() );
+        typename Partitioner::split_type split_obj;
+        start_for b( *this, split_obj );
         this->execute(); // Execute the left interval first to keep the serial order.
         b.execute();     // Execute the right interval then.
     }
 }
 
-//! Parallel iteration over range with default partitioner..
+//! Parallel iteration over range with default partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body ) {
-    serial::interface6::start_for<Range,Body,auto_partitioner>::run(range,body,auto_partitioner());
+    serial::interface7::start_for<Range,Body,const __TBB_DEFAULT_PARTITIONER>::run(range,body,__TBB_DEFAULT_PARTITIONER());
 }
 
 //! Parallel iteration over range with simple partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) {
-    serial::interface6::start_for<Range,Body,simple_partitioner>::run(range,body,partitioner);
+    serial::interface7::start_for<Range,Body,const simple_partitioner>::run(range,body,partitioner);
 }
 
 //! Parallel iteration over range with auto_partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) {
-    serial::interface6::start_for<Range,Body,auto_partitioner>::run(range,body,partitioner);
+    serial::interface7::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner);
 }
 
 //! Parallel iteration over range with affinity_partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, affinity_partitioner& partitioner ) {
-    serial::interface6::start_for<Range,Body,affinity_partitioner>::run(range,body,partitioner);
+    serial::interface7::start_for<Range,Body,affinity_partitioner>::run(range,body,partitioner);
 }
 
-//! Parallel iteration over a range of integers with a step value
-template <typename Index, typename Function>
-void parallel_for(Index first, Index last, Index step, const Function& f) {
+//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner (ignored)
+template <typename Index, typename Function, typename Partitioner>
+void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& ) {
     if (step <= 0 )
         throw std::invalid_argument( "nonpositive_step" );
     else if (last > first) {
@@ -152,20 +145,56 @@ void parallel_for(Index first, Index last, Index step, const Function& f) {
     }
 }
 
-//! Parallel iteration over a range of integers with a default step value
+//! Parallel iteration over a range of integers with explicit step and default partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, auto_partitioner());
+}
+//! Parallel iteration over a range of integers with explicit step and simple partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& p) {
+    parallel_for_impl<Index,Function,const simple_partitioner>(first, last, step, f, p);
+}
+//! Parallel iteration over a range of integers with explicit step and auto partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& p) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, p);
+}
+//! Parallel iteration over a range of integers with explicit step and affinity partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& p) {
+    parallel_for_impl(first, last, step, f, p);
+}
+
+//! Parallel iteration over a range of integers with default step and default partitioner
 template <typename Index, typename Function>
 void parallel_for(Index first, Index last, const Function& f) {
-    parallel_for(first, last, static_cast<Index>(1), f);
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, auto_partitioner());
+}
+//! Parallel iteration over a range of integers with default step and simple partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& p) {
+    parallel_for_impl<Index,Function,const simple_partitioner>(first, last, static_cast<Index>(1), f, p);
+}
+//! Parallel iteration over a range of integers with default step and auto partitioner
+template <typename Index, typename Function>
+    void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& p) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, p);
+}
+//! Parallel iteration over a range of integers with default step and affinity_partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& p) {
+    parallel_for_impl(first, last, static_cast<Index>(1), f, p);
 }
 
-} // namespace interface6
+} // namespace interface7
 
-using interface6::parallel_for;
+using interface7::parallel_for;
 
 } // namespace serial
 
 #ifndef __TBB_NORMAL_EXECUTION
-using serial::interface6::parallel_for;
+using serial::interface7::parallel_for;
 #endif
 
 } // namespace tbb
index 5aeb6eacc6a2bcd8821ede7b4458f7a7819f3d05..2024cf644f4bac8dc41ccf238e8399e9fdba9943 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_annotate_H
diff --git a/dependencies64/tbb/include/tbb/aggregator.h b/dependencies64/tbb/include/tbb/aggregator.h
new file mode 100644 (file)
index 0000000..8a28ed0
--- /dev/null
@@ -0,0 +1,202 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB__aggregator_H
+#define __TBB__aggregator_H
+
+#if !TBB_PREVIEW_AGGREGATOR
+#error Set TBB_PREVIEW_AGGREGATOR before including aggregator.h
+#endif
+
+#include "atomic.h"
+#include "tbb_profiling.h"
+
+namespace tbb {
+namespace interface6 {
+
+using namespace tbb::internal;
+
+class aggregator_operation {
+    template<typename handler_type> friend class aggregator_ext;
+    uintptr_t status;
+    aggregator_operation* my_next;
+public:
+    enum aggregator_operation_status { agg_waiting=0, agg_finished };
+    aggregator_operation() : status(agg_waiting), my_next(NULL) {}
+    /// Call start before handling this operation
+    void start() { call_itt_notify(acquired, &status); }
+    /// Call finish when done handling this operation
+    /** The operation will be released to its originating thread, and possibly deleted. */
+    void finish() { itt_store_word_with_release(status, uintptr_t(agg_finished)); }
+    aggregator_operation* next() { return itt_hide_load_word(my_next);}
+    void set_next(aggregator_operation* n) { itt_hide_store_word(my_next, n); }
+};
+
+namespace internal {
+
+class basic_operation_base : public aggregator_operation {
+    friend class basic_handler;
+    virtual void apply_body() = 0;
+public:
+    basic_operation_base() : aggregator_operation() {}
+    virtual ~basic_operation_base() {}
+};
+
+template<typename Body>
+class basic_operation : public basic_operation_base, no_assign {
+    const Body& my_body;
+    /*override*/ void apply_body() { my_body(); }
+public:
+    basic_operation(const Body& b) : basic_operation_base(), my_body(b) {}
+};
+
+class basic_handler {
+public:
+    basic_handler() {}
+    void operator()(aggregator_operation* op_list) const { 
+        while (op_list) {
+            // ITT note: &(op_list->status) tag is used to cover accesses to the operation data.
+            // The executing thread "acquires" the tag (see start()) and then performs
+            // the associated operation w/o triggering a race condition diagnostics.
+            // A thread that created the operation is waiting for its status (see execute_impl()),
+            // so when this thread is done with the operation, it will "release" the tag 
+            // and update the status (see finish()) to give control back to the waiting thread.
+            basic_operation_base& request = static_cast<basic_operation_base&>(*op_list);
+            // IMPORTANT: need to advance op_list to op_list->next() before calling request.finish()
+            op_list = op_list->next();
+            request.start();
+            request.apply_body();
+            request.finish();
+        }
+    }
+};
+
+} // namespace internal
+
+//! Aggregator base class and expert interface
+/** An aggregator for collecting operations coming from multiple sources and executing
+    them serially on a single thread. */
+template <typename handler_type>
+class aggregator_ext : tbb::internal::no_copy {
+public:
+    aggregator_ext(const handler_type& h) : handler_busy(0), handle_operations(h) { mailbox = NULL; }
+
+    //! EXPERT INTERFACE: Enter a user-made operation into the aggregator's mailbox.
+    /** Details of user-made operations must be handled by user-provided handler */
+    void process(aggregator_operation *op) { execute_impl(*op); }
+
+ protected:
+    /** Place operation in mailbox, then either handle mailbox or wait for the operation 
+        to be completed by a different thread. */
+    void execute_impl(aggregator_operation& op) {
+        aggregator_operation* res;
+
+        // ITT note: &(op.status) tag is used to cover accesses to this operation. This
+        // thread has created the operation, and now releases it so that the handler
+        // thread may handle the associated operation w/o triggering a race condition;
+        // thus this tag will be acquired just before the operation is handled in the
+        // handle_operations functor.
+        call_itt_notify(releasing, &(op.status));
+        // insert the operation in the queue
+        do {
+            // ITT may flag the following line as a race; it is a false positive:
+            // This is an atomic read; we don't provide itt_hide_load_word for atomics
+            op.my_next = res = mailbox; // NOT A RACE 
+        } while (mailbox.compare_and_swap(&op, res) != res);
+        if (!res) { // first in the list; handle the operations
+            // ITT note: &mailbox tag covers access to the handler_busy flag, which this
+            // waiting handler thread will try to set before entering handle_operations.
+            call_itt_notify(acquired, &mailbox);
+            start_handle_operations();
+            __TBB_ASSERT(op.status, NULL);
+        }
+        else { // not first; wait for op to be ready
+            call_itt_notify(prepare, &(op.status));
+            spin_wait_while_eq(op.status, uintptr_t(aggregator_operation::agg_waiting));
+            itt_load_word_with_acquire(op.status);
+        }
+    }
+
+
+ private:
+    //! An atomically updated list (aka mailbox) of aggregator_operations
+    atomic<aggregator_operation *> mailbox;
+
+    //! Controls thread access to handle_operations
+    /** Behaves as boolean flag where 0=false, 1=true */
+    uintptr_t handler_busy;
+
+    handler_type handle_operations;
+
+    //! Trigger the handling of operations when the handler is free
+    void start_handle_operations() {
+        aggregator_operation *pending_operations;
+
+        // ITT note: &handler_busy tag covers access to mailbox as it is passed
+        // between active and waiting handlers.  Below, the waiting handler waits until
+        // the active handler releases, and the waiting handler acquires &handler_busy as
+        // it becomes the active_handler. The release point is at the end of this
+        // function, when all operations in mailbox have been handled by the
+        // owner of this aggregator.
+        call_itt_notify(prepare, &handler_busy);
+        // get handler_busy: only one thread can possibly spin here at a time
+        spin_wait_until_eq(handler_busy, uintptr_t(0));
+        call_itt_notify(acquired, &handler_busy);
+        // acquire fence not necessary here due to causality rule and surrounding atomics
+        __TBB_store_with_release(handler_busy, uintptr_t(1));
+
+        // ITT note: &mailbox tag covers access to the handler_busy flag itself. 
+        // Capturing the state of the mailbox signifies that handler_busy has been 
+        // set and a new active handler will now process that list's operations.
+        call_itt_notify(releasing, &mailbox);
+        // grab pending_operations
+        pending_operations = mailbox.fetch_and_store(NULL);
+
+        // handle all the operations
+        handle_operations(pending_operations);
+
+        // release the handler
+        itt_store_word_with_release(handler_busy, uintptr_t(0));
+    }
+};
+
+//! Basic aggregator interface
+class aggregator : private aggregator_ext<internal::basic_handler> {
+public:
+    aggregator() : aggregator_ext<internal::basic_handler>(internal::basic_handler()) {}
+    //! BASIC INTERFACE: Enter a function for exclusive execution by the aggregator.
+    /** The calling thread stores the function object in a basic_operation and
+        places the operation in the aggregator's mailbox */
+    template<typename Body>
+    void execute(const Body& b) {
+        internal::basic_operation<Body> op(b);
+        this->execute_impl(op);
+    }
+};
+
+} // namespace interface6
+
+using interface6::aggregator;
+using interface6::aggregator_ext;
+using interface6::aggregator_operation;
+
+} // namespace tbb
+
+#endif  // __TBB__aggregator_H
index 7d642fb9bcc8f95516b14f69d64d8f7415018cb0..d2015972d2a50ea81a2ba2cede90713c58f5db9a 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_aligned_space_H
@@ -37,7 +29,7 @@ namespace tbb {
 //! Block of space aligned sufficiently to construct an array T with N elements.
 /** The elements are not constructed or destroyed by this class.
     @ingroup memory_allocation */
-template<typename T,size_t N>
+template<typename T,size_t N=1>
 class aligned_space {
 private:
     typedef __TBB_TypeWithAlignmentAtLeastAsStrict(T) element_type;
index 5257ff59ee07f9ae30d8f60d5e833a66d03ffeac..45bf317402bbb3863969fe5f9d8907292b5e6313 100644 (file)
@@ -1,38 +1,29 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_atomic_H
 #define __TBB_atomic_H
 
 #include <cstddef>
-#include "tbb_stddef.h"
 
-#if _MSC_VER 
+#if _MSC_VER
 #define __TBB_LONG_LONG __int64
 #else
 #define __TBB_LONG_LONG long long
 #include "tbb_machine.h"
 
 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
-    // Workaround for overzealous compiler warnings 
+    // Workaround for overzealous compiler warnings
     #pragma warning (push)
-    #pragma warning (disable: 4244 4267)
+    #pragma warning (disable: 4244 4267 4512)
 #endif
 
 namespace tbb {
 
-//! Specifies memory fencing.
+//! Specifies memory semantics.
 enum memory_semantics {
-    //! Sequentially consistent fence.
+    //! Sequential consistency
     full_fence,
-    //! Acquire fence
+    //! Acquire
     acquire,
-    //! Release fence
+    //! Release
     release,
     //! No ordering
     relaxed
@@ -67,7 +58,7 @@ namespace internal {
     #define __TBB_DECL_ATOMIC_FIELD(t,f,a) t f  __attribute__ ((aligned(a)));
 #elif __TBB_DECLSPEC_ALIGN_PRESENT
     #define __TBB_DECL_ATOMIC_FIELD(t,f,a) __declspec(align(a)) t f;
-#else 
+#else
     #error Do not know syntax for forcing alignment.
 #endif
 
@@ -77,31 +68,64 @@ struct atomic_rep;           // Primary template declared, but never defined.
 template<>
 struct atomic_rep<1> {       // Specialization
     typedef int8_t word;
-    int8_t value;
 };
 template<>
 struct atomic_rep<2> {       // Specialization
     typedef int16_t word;
-    __TBB_DECL_ATOMIC_FIELD(int16_t,value,2)
 };
 template<>
 struct atomic_rep<4> {       // Specialization
-#if _MSC_VER && __TBB_WORDSIZE==4
+#if _MSC_VER && !_WIN64
     // Work-around that avoids spurious /Wp64 warnings
     typedef intptr_t word;
 #else
     typedef int32_t word;
 #endif
-    __TBB_DECL_ATOMIC_FIELD(int32_t,value,4)
 };
 #if __TBB_64BIT_ATOMICS
 template<>
 struct atomic_rep<8> {       // Specialization
     typedef int64_t word;
-    __TBB_DECL_ATOMIC_FIELD(int64_t,value,8)
 };
 #endif
 
+template<typename value_type, size_t size>
+struct aligned_storage;
+
+//the specializations are needed to please MSVC syntax of __declspec(align()) which accept _literal_ constants only
+#if __TBB_ATOMIC_CTORS
+    #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S)                  \
+    template<typename value_type>                                     \
+    struct aligned_storage<value_type,S> {                            \
+        __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S)                \
+        aligned_storage() = default ;                                 \
+        constexpr aligned_storage(value_type value):my_value(value){} \
+    };                                                                \
+
+#else
+    #define ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(S)                  \
+    template<typename value_type>                                     \
+    struct aligned_storage<value_type,S> {                            \
+        __TBB_DECL_ATOMIC_FIELD(value_type,my_value,S)                \
+    };                                                                \
+
+#endif
+
+template<typename value_type>
+struct aligned_storage<value_type,1> {
+    value_type my_value;
+#if __TBB_ATOMIC_CTORS
+    aligned_storage() = default ;
+    constexpr aligned_storage(value_type value):my_value(value){}
+#endif
+};
+
+ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(2)
+ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(4)
+#if __TBB_64BIT_ATOMICS
+ATOMIC_STORAGE_PARTIAL_SPECIALIZATION(8)
+#endif
+
 template<size_t Size, memory_semantics M>
 struct atomic_traits;        // Primary template declared, but not defined.
 
@@ -188,27 +212,71 @@ __TBB_DECL_ATOMIC_LOAD_STORE_PRIMITIVES(relaxed);
 #define __TBB_MINUS_ONE(T) (T(T(0)-T(1)))
 
 //! Base class that provides basic functionality for atomic<T> without fetch_and_add.
-/** Works for any type T that has the same size as an integral type, has a trivial constructor/destructor, 
+/** Works for any type T that has the same size as an integral type, has a trivial constructor/destructor,
     and can be copied/compared by memcpy/memcmp. */
 template<typename T>
 struct atomic_impl {
 protected:
-    atomic_rep<sizeof(T)> rep;
+    aligned_storage<T,sizeof(T)> my_storage;
 private:
+    //TODO: rechecks on recent versions of gcc if union is still the _only_ way to do a conversion without warnings
     //! Union type used to convert type T to underlying integral type.
+    template<typename value_type>
     union converter {
-        T value;
-        typename atomic_rep<sizeof(T)>::word bits;
+        typedef typename atomic_rep<sizeof(value_type)>::word bits_type;
+        converter(){}
+        converter(value_type a_value) : value(a_value) {}
+        value_type value;
+        bits_type bits;
     };
+
+    template<typename value_t>
+    static typename converter<value_t>::bits_type to_bits(value_t value){
+        return converter<value_t>(value).bits;
+    }
+    template<typename value_t>
+    static value_t to_value(typename converter<value_t>::bits_type bits){
+        converter<value_t> u;
+        u.bits = bits;
+        return u.value;
+    }
+
+    template<typename value_t>
+    union ptr_converter;            //Primary template declared, but never defined.
+
+    template<typename value_t>
+    union ptr_converter<value_t *> {
+        ptr_converter(){}
+        ptr_converter(value_t* a_value) : value(a_value) {}
+        value_t* value;
+        uintptr_t bits;
+    };
+    //TODO: check if making to_bits accepting reference (thus unifying it with to_bits_ref)
+    //does not hurt performance
+    template<typename value_t>
+    static typename converter<value_t>::bits_type & to_bits_ref(value_t& value){
+        //TODO: this #ifdef is temporary workaround, as union conversion seems to fail
+        //on suncc for 64 bit types for 32 bit target
+        #if !__SUNPRO_CC
+            return *(typename converter<value_t>::bits_type*)ptr_converter<value_t*>(&value).bits;
+        #else
+            return *(typename converter<value_t>::bits_type*)(&value);
+        #endif
+    }
+
+
 public:
     typedef T value_type;
 
+#if __TBB_ATOMIC_CTORS
+    atomic_impl() = default ;
+    constexpr atomic_impl(value_type value):my_storage(value){}
+#endif
     template<memory_semantics M>
     value_type fetch_and_store( value_type value ) {
-        converter u, w;
-        u.value = value;
-        w.bits = internal::atomic_traits<sizeof(value_type),M>::fetch_and_store(&rep.value,u.bits);
-        return w.value;
+          return to_value<value_type>(
+                  internal::atomic_traits<sizeof(value_type),M>::fetch_and_store( &my_storage.my_value, to_bits(value) )
+          );
     }
 
     value_type fetch_and_store( value_type value ) {
@@ -217,28 +285,26 @@ public:
 
     template<memory_semantics M>
     value_type compare_and_swap( value_type value, value_type comparand ) {
-        converter u, v, w;
-        u.value = value;
-        v.value = comparand;
-        w.bits = internal::atomic_traits<sizeof(value_type),M>::compare_and_swap(&rep.value,u.bits,v.bits);
-        return w.value;
+        return to_value<value_type>(
+                internal::atomic_traits<sizeof(value_type),M>::compare_and_swap( &my_storage.my_value, to_bits(value), to_bits(comparand) )
+        );
     }
 
     value_type compare_and_swap( value_type value, value_type comparand ) {
         return compare_and_swap<full_fence>(value,comparand);
     }
 
-    operator value_type() const volatile {                // volatile qualifier here for backwards compatibility 
-        converter w;
-        w.bits = __TBB_load_with_acquire( rep.value );
-        return w.value;
+    operator value_type() const volatile {                // volatile qualifier here for backwards compatibility
+        return  to_value<value_type>(
+                __TBB_load_with_acquire( to_bits_ref(my_storage.my_value) )
+        );
     }
 
     template<memory_semantics M>
     value_type load () const {
-        converter u;
-        u.bits = internal::atomic_load_store_traits<M>::load( rep.value );
-        return u.value;
+        return to_value<value_type>(
+                internal::atomic_load_store_traits<M>::load( to_bits_ref(my_storage.my_value) )
+        );
     }
 
     value_type load () const {
@@ -247,9 +313,7 @@ public:
 
     template<memory_semantics M>
     void store ( value_type value ) {
-        converter u;
-        u.value = value;
-        internal::atomic_load_store_traits<M>::store( rep.value, u.bits );
+        internal::atomic_load_store_traits<M>::store( to_bits_ref(my_storage.my_value), to_bits(value));
     }
 
     void store ( value_type value ) {
@@ -258,9 +322,8 @@ public:
 
 protected:
     value_type store_with_release( value_type rhs ) {
-        converter u;
-        u.value = rhs;
-        __TBB_store_with_release(rep.value,u.bits);
+       //TODO: unify with store<release>
+        __TBB_store_with_release( to_bits_ref(my_storage.my_value), to_bits(rhs) );
         return rhs;
     }
 };
@@ -273,10 +336,13 @@ template<typename I, typename D, typename StepType>
 struct atomic_impl_with_arithmetic: atomic_impl<I> {
 public:
     typedef I value_type;
-
+#if    __TBB_ATOMIC_CTORS
+    atomic_impl_with_arithmetic() = default ;
+    constexpr atomic_impl_with_arithmetic(value_type value): atomic_impl<I>(value){}
+#endif
     template<memory_semantics M>
     value_type fetch_and_add( D addend ) {
-        return value_type(internal::atomic_traits<sizeof(value_type),M>::fetch_and_add( &this->rep.value, addend*sizeof(StepType) ));
+        return value_type(internal::atomic_traits<sizeof(value_type),M>::fetch_and_add( &this->my_storage.my_value, addend*sizeof(StepType) ));
     }
 
     value_type fetch_and_add( D addend ) {
@@ -302,14 +368,14 @@ public:
     }
 
 public:
-    value_type operator+=( D addend ) {
-        return fetch_and_add(addend)+addend;
+    value_type operator+=( D value ) {
+        return fetch_and_add(value)+value;
     }
 
-    value_type operator-=( D addend ) {
-        // Additive inverse of addend computed using binary minus,
+    value_type operator-=( D value ) {
+        // Additive inverse of value computed using binary minus,
         // instead of unary minus, for sake of avoiding compiler warnings.
-        return operator+=(D(0)-addend);    
+        return operator+=(D(0)-value);
     }
 
     value_type operator++() {
@@ -337,6 +403,10 @@ public:
     @ingroup synchronization */
 template<typename T>
 struct atomic: internal::atomic_impl<T> {
+#if __TBB_ATOMIC_CTORS
+    atomic() = default;
+    constexpr atomic(T arg): internal::atomic_impl<T>(arg) {}
+#endif
     T operator=( T rhs ) {
         // "this" required here in strict ISO C++ because store_with_release is a dependent name
         return this->store_with_release(rhs);
@@ -344,13 +414,25 @@ struct atomic: internal::atomic_impl<T> {
     atomic<T>& operator=( const atomic<T>& rhs ) {this->store_with_release(rhs); return *this;}
 };
 
-#define __TBB_DECL_ATOMIC(T) \
-    template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {  \
-        T operator=( T rhs ) {return store_with_release(rhs);}  \
-        atomic<T>& operator=( const atomic<T>& rhs ) {store_with_release(rhs); return *this;}  \
-    };
+#if __TBB_ATOMIC_CTORS
+    #define __TBB_DECL_ATOMIC(T)                                                                    \
+        template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {              \
+            atomic() = default;                                                                     \
+            constexpr atomic(T arg): internal::atomic_impl_with_arithmetic<T,T,char>(arg) {}        \
+                                                                                                    \
+            T operator=( T rhs ) {return store_with_release(rhs);}                                  \
+            atomic<T>& operator=( const atomic<T>& rhs ) {store_with_release(rhs); return *this;}   \
+        };
+#else
+    #define __TBB_DECL_ATOMIC(T)                                                                    \
+        template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {              \
+            T operator=( T rhs ) {return store_with_release(rhs);}                                  \
+            atomic<T>& operator=( const atomic<T>& rhs ) {store_with_release(rhs); return *this;}   \
+        };
+#endif
 
 #if __TBB_64BIT_ATOMICS
+//TODO: consider adding non-default (and atomic) copy constructor for 32bit platform
 __TBB_DECL_ATOMIC(__TBB_LONG_LONG)
 __TBB_DECL_ATOMIC(unsigned __TBB_LONG_LONG)
 #else
@@ -359,23 +441,33 @@ __TBB_DECL_ATOMIC(unsigned __TBB_LONG_LONG)
 __TBB_DECL_ATOMIC(long)
 __TBB_DECL_ATOMIC(unsigned long)
 
-#if defined(_MSC_VER) && __TBB_WORDSIZE==4
-/* Special version of __TBB_DECL_ATOMIC that avoids gratuitous warnings from cl /Wp64 option. 
-   It is identical to __TBB_DECL_ATOMIC(unsigned) except that it replaces operator=(T) 
+#if _MSC_VER && !_WIN64
+#if __TBB_ATOMIC_CTORS
+/* Special version of __TBB_DECL_ATOMIC that avoids gratuitous warnings from cl /Wp64 option.
+   It is identical to __TBB_DECL_ATOMIC(unsigned) except that it replaces operator=(T)
    with an operator=(U) that explicitly converts the U to a T.  Types T and U should be
    type synonyms on the platform.  Type U should be the wider variant of T from the
    perspective of /Wp64. */
 #define __TBB_DECL_ATOMIC_ALT(T,U) \
-    template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {  \
-        T operator=( U rhs ) {return store_with_release(T(rhs));}  \
+    template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {             \
+        atomic() = default ;                                                                   \
+        constexpr atomic(T arg): internal::atomic_impl_with_arithmetic<T,T,char>(arg) {}       \
+        T operator=( U rhs ) {return store_with_release(T(rhs));}                              \
+        atomic<T>& operator=( const atomic<T>& rhs ) {store_with_release(rhs); return *this;}  \
+    };
+#else
+#define __TBB_DECL_ATOMIC_ALT(T,U) \
+    template<> struct atomic<T>: internal::atomic_impl_with_arithmetic<T,T,char> {             \
+        T operator=( U rhs ) {return store_with_release(T(rhs));}                              \
         atomic<T>& operator=( const atomic<T>& rhs ) {store_with_release(rhs); return *this;}  \
     };
+#endif
 __TBB_DECL_ATOMIC_ALT(unsigned,size_t)
 __TBB_DECL_ATOMIC_ALT(int,ptrdiff_t)
 #else
 __TBB_DECL_ATOMIC(unsigned)
 __TBB_DECL_ATOMIC(int)
-#endif /* defined(_MSC_VER) && __TBB_WORDSIZE==4 */
+#endif /* _MSC_VER && !_WIN64 */
 
 __TBB_DECL_ATOMIC(unsigned short)
 __TBB_DECL_ATOMIC(short)
@@ -383,12 +475,16 @@ __TBB_DECL_ATOMIC(char)
 __TBB_DECL_ATOMIC(signed char)
 __TBB_DECL_ATOMIC(unsigned char)
 
-#if !defined(_MSC_VER)||defined(_NATIVE_WCHAR_T_DEFINED) 
+#if !_MSC_VER || defined(_NATIVE_WCHAR_T_DEFINED)
 __TBB_DECL_ATOMIC(wchar_t)
 #endif /* _MSC_VER||!defined(_NATIVE_WCHAR_T_DEFINED) */
 
 //! Specialization for atomic<T*> with arithmetic and operator->.
 template<typename T> struct atomic<T*>: internal::atomic_impl_with_arithmetic<T*,ptrdiff_t,T> {
+#if __TBB_ATOMIC_CTORS
+    atomic() = default ;
+    constexpr atomic(T* arg): internal::atomic_impl_with_arithmetic<T*,ptrdiff_t,T>(arg) {}
+#endif
     T* operator=( T* rhs ) {
         // "this" required here in strict ISO C++ because store_with_release is a dependent name
         return this->store_with_release(rhs);
@@ -403,6 +499,10 @@ template<typename T> struct atomic<T*>: internal::atomic_impl_with_arithmetic<T*
 
 //! Specialization for atomic<void*>, for sake of not allowing arithmetic or operator->.
 template<> struct atomic<void*>: internal::atomic_impl<void*> {
+#if __TBB_ATOMIC_CTORS
+    atomic() = default ;
+    constexpr atomic(void* arg): internal::atomic_impl<void*>(arg) {}
+#endif
     void* operator=( void* rhs ) {
         // "this" required here in strict ISO C++ because store_with_release is a dependent name
         return this->store_with_release(rhs);
@@ -419,11 +519,37 @@ template <memory_semantics M, typename T>
 T load ( const atomic<T>& a ) { return a.template load<M>(); }
 
 template <memory_semantics M, typename T>
-void store ( atomic<T>& a, T value ) { return a.template store<M>(value); }
+void store ( atomic<T>& a, T value ) { a.template store<M>(value); }
+
+namespace interface6{
+//! Make an atomic for use in an initialization (list), as an alternative to zero-initialization or normal assignment.
+template<typename T>
+atomic<T> make_atomic(T t) {
+    atomic<T> a;
+    store<relaxed>(a,t);
+    return a;
+}
+}
+using interface6::make_atomic;
+
+namespace internal {
+template<memory_semantics M, typename T >
+void swap(atomic<T> & lhs, atomic<T> & rhs){
+    T tmp = load<M>(lhs);
+    store<M>(lhs,load<M>(rhs));
+    store<M>(rhs,tmp);
+}
+
+// only to aid in the gradual conversion of ordinary variables to proper atomics
+template<typename T>
+inline atomic<T>& as_atomic( T& t ) {
+    return (atomic<T>&)t;
+}
+} // namespace tbb::internal
 
 } // namespace tbb
 
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+#if _MSC_VER && !__INTEL_COMPILER
     #pragma warning (pop)
 #endif // warnings 4244, 4267 are back
 
index ccba50148c10794e03946104ec1f673c156dc0ca..41233476ebcef65c0b3758c406225dfa126358c2 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_blocked_range_H
@@ -60,8 +52,8 @@ public:
     blocked_range() : my_end(), my_begin() {}
 
     //! Construct range over half-open interval [begin,end), with the given grainsize.
-    blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) : 
-        my_end(end_), my_begin(begin_), my_grainsize(grainsize_) 
+    blocked_range( Value begin_, Value end_, size_type grainsize_=1 ) :
+        my_end(end_), my_begin(begin_), my_grainsize(grainsize_)
     {
         __TBB_ASSERT( my_grainsize>0, "grainsize must be positive" );
     }
@@ -93,14 +85,34 @@ public:
     /** Unspecified if end()<begin(). */
     bool is_divisible() const {return my_grainsize<size();}
 
-    //! Split range.  
-    /** The new Range *this has the second half, the old range r has the first half. 
+    //! Split range.
+    /** The new Range *this has the second part, the old range r has the first part.
         Unspecified if end()<begin() or !is_divisible(). */
-    blocked_range( blocked_range& r, split ) : 
+    blocked_range( blocked_range& r, split ) :
         my_end(r.my_end),
-        my_begin(do_split(r)),
+        my_begin(do_split(r, split())),
         my_grainsize(r.my_grainsize)
-    {}
+    {
+        // only comparison 'less than' is required from values of blocked_range objects
+        __TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "blocked_range has been split incorrectly" );
+    }
+
+#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
+    //! Static field to support proportional split
+    static const bool is_splittable_in_proportion = true;
+
+    //! Split range.
+    /** The new Range *this has the second part split according to specified proportion, the old range r has the first part.
+        Unspecified if end()<begin() or !is_divisible(). */
+    blocked_range( blocked_range& r, proportional_split& proportion ) :
+        my_end(r.my_end),
+        my_begin(do_split(r, proportion)),
+        my_grainsize(r.my_grainsize)
+    {
+        // only comparison 'less than' is required from values of blocked_range objects
+        __TBB_ASSERT( !(my_begin < r.my_end) && !(r.my_end < my_begin), "blocked_range has been split incorrectly" );
+    }
+#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
 
 private:
     /** NOTE: my_end MUST be declared before my_begin, otherwise the forking constructor will break. */
@@ -110,13 +122,31 @@ private:
 
     //! Auxiliary function used by forking constructor.
     /** Using this function lets us not require that Value support assignment or default construction. */
-    static Value do_split( blocked_range& r ) {
+    static Value do_split( blocked_range& r, split )
+    {
         __TBB_ASSERT( r.is_divisible(), "cannot split blocked_range that is not divisible" );
-        Value middle = r.my_begin + (r.my_end-r.my_begin)/2u;
+        Value middle = r.my_begin + (r.my_end - r.my_begin) / 2u;
         r.my_end = middle;
         return middle;
     }
 
+#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
+    static Value do_split( blocked_range& r, proportional_split& proportion )
+    {
+        __TBB_ASSERT( r.is_divisible(), "cannot split blocked_range that is not divisible" );
+
+        // usage of 32-bit floating point arithmetic is not enough to handle ranges of
+        // more than 2^24 iterations accurately. However, even on ranges with 2^64
+        // iterations the computational error approximately equals to 0.000001% which
+        // makes small impact on uniform distribution of such range's iterations (assuming
+        // all iterations take equal time to complete). See 'test_partitioner_whitebox'
+        // for implementation of an exact split algorithm
+        size_type right_part = size_type(float(r.size()) * float(proportion.right())
+                                         / float(proportion.left() + proportion.right()) + 0.5f);
+        return r.my_end = Value(r.my_end - right_part);
+    }
+#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
+
     template<typename RowValue, typename ColValue>
     friend class blocked_range2d;
 
@@ -124,6 +154,6 @@ private:
     friend class blocked_range3d;
 };
 
-} // namespace tbb 
+} // namespace tbb
 
 #endif /* __TBB_blocked_range_H */
index 5fb182f3c86a2b8e160ae191cce65b75f2fa85d8..8bec6a7b869624cf5955c02acc376542c3f3cbf0 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_blocked_range2d_H
@@ -42,7 +34,7 @@ public:
     //! Type for size of an iteration range
     typedef blocked_range<RowValue> row_range_type;
     typedef blocked_range<ColValue> col_range_type;
+
 private:
     row_range_type my_rows;
     col_range_type my_cols;
@@ -50,14 +42,14 @@ private:
 public:
 
     blocked_range2d( RowValue row_begin, RowValue row_end, typename row_range_type::size_type row_grainsize,
-                     ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) : 
+                     ColValue col_begin, ColValue col_end, typename col_range_type::size_type col_grainsize ) :
         my_rows(row_begin,row_end,row_grainsize),
         my_cols(col_begin,col_end,col_grainsize)
     {
     }
 
     blocked_range2d( RowValue row_begin, RowValue row_end,
-                     ColValue col_begin, ColValue col_end ) : 
+                     ColValue col_begin, ColValue col_end ) :
         my_rows(row_begin,row_end),
         my_cols(col_begin,col_end)
     {
@@ -74,24 +66,43 @@ public:
         return my_rows.is_divisible() || my_cols.is_divisible();
     }
 
-    blocked_range2d( blocked_range2d& r, split ) : 
+    blocked_range2d( blocked_range2d& r, split ) :
+        my_rows(r.my_rows),
+        my_cols(r.my_cols)
+    {
+        split split_obj;
+        do_split(r, split_obj);
+    }
+
+#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
+    //! Static field to support proportional split
+    static const bool is_splittable_in_proportion = true;
+
+    blocked_range2d( blocked_range2d& r, proportional_split& proportion ) :
         my_rows(r.my_rows),
         my_cols(r.my_cols)
+    {
+        do_split(r, proportion);
+    }
+#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
+
+    template <typename Split>
+    void do_split( blocked_range2d& r, Split& split_obj )
     {
         if( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) {
-            my_cols.my_begin = col_range_type::do_split(r.my_cols);
+            my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj);
         } else {
-            my_rows.my_begin = row_range_type::do_split(r.my_rows);
+            my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj);
         }
     }
 
-    //! The rows of the iteration space 
+    //! The rows of the iteration space
     const row_range_type& rows() const {return my_rows;}
 
-    //! The columns of the iteration space 
+    //! The columns of the iteration space
     const col_range_type& cols() const {return my_cols;}
 };
 
-} // namespace tbb 
+} // namespace tbb
 
 #endif /* __TBB_blocked_range2d_H */
index f6f58de6b2763720088b2e9cf68a2e5fce566acd..a359e241fc6143107e56dac40849c2df0d419080 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_blocked_range3d_H
@@ -43,7 +35,7 @@ public:
     typedef blocked_range<PageValue> page_range_type;
     typedef blocked_range<RowValue>  row_range_type;
     typedef blocked_range<ColValue>  col_range_type;
+
 private:
     page_range_type my_pages;
     row_range_type  my_rows;
@@ -53,16 +45,16 @@ public:
 
     blocked_range3d( PageValue page_begin, PageValue page_end,
                      RowValue  row_begin,  RowValue row_end,
-                     ColValue  col_begin,  ColValue col_end ) : 
+                     ColValue  col_begin,  ColValue col_end ) :
         my_pages(page_begin,page_end),
         my_rows(row_begin,row_end),
         my_cols(col_begin,col_end)
     {
     }
 
-    blocked_range3d( PageValue page_begin, PageValue page_end, typename page_range_type::size_type page_grainsize, 
+    blocked_range3d( PageValue page_begin, PageValue page_end, typename page_range_type::size_type page_grainsize,
                      RowValue  row_begin,  RowValue row_end,   typename row_range_type::size_type row_grainsize,
-                     ColValue  col_begin,  ColValue col_end,   typename col_range_type::size_type col_grainsize ) :  
+                     ColValue  col_begin,  ColValue col_end,   typename col_range_type::size_type col_grainsize ) :
         my_pages(page_begin,page_end,page_grainsize),
         my_rows(row_begin,row_end,row_grainsize),
         my_cols(col_begin,col_end,col_grainsize)
@@ -80,37 +72,57 @@ public:
         return  my_pages.is_divisible() || my_rows.is_divisible() || my_cols.is_divisible();
     }
 
-    blocked_range3d( blocked_range3d& r, split ) : 
+    blocked_range3d( blocked_range3d& r, split ) :
         my_pages(r.my_pages),
         my_rows(r.my_rows),
         my_cols(r.my_cols)
     {
-        if( my_pages.size()*double(my_rows.grainsize()) < my_rows.size()*double(my_pages.grainsize()) ) {
+        split split_obj;
+        do_split(r, split_obj);
+    }
+
+#if __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
+    //! Static field to support proportional split
+    static const bool is_splittable_in_proportion = true;
+
+    blocked_range3d( blocked_range3d& r, proportional_split& proportion ) :
+        my_pages(r.my_pages),
+        my_rows(r.my_rows),
+        my_cols(r.my_cols)
+    {
+        do_split(r, proportion);
+    }
+#endif /* __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES */
+
+    template <typename Split>
+    void do_split( blocked_range3d& r, Split& split_obj)
+    {
+        if ( my_pages.size()*double(my_rows.grainsize()) < my_rows.size()*double(my_pages.grainsize()) ) {
             if ( my_rows.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_rows.grainsize()) ) {
-                my_cols.my_begin = col_range_type::do_split(r.my_cols);
+                my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj);
             } else {
-                my_rows.my_begin = row_range_type::do_split(r.my_rows);
+                my_rows.my_begin = row_range_type::do_split(r.my_rows, split_obj);
             }
        } else {
             if ( my_pages.size()*double(my_cols.grainsize()) < my_cols.size()*double(my_pages.grainsize()) ) {
-                my_cols.my_begin = col_range_type::do_split(r.my_cols);
+                my_cols.my_begin = col_range_type::do_split(r.my_cols, split_obj);
             } else {
-                    my_pages.my_begin = page_range_type::do_split(r.my_pages);
+                my_pages.my_begin = page_range_type::do_split(r.my_pages, split_obj);
             }
         }
     }
 
-    //! The pages of the iteration space 
+    //! The pages of the iteration space
     const page_range_type& pages() const {return my_pages;}
 
-    //! The rows of the iteration space 
+    //! The rows of the iteration space
     const row_range_type& rows() const {return my_rows;}
 
-    //! The columns of the iteration space 
+    //! The columns of the iteration space
     const col_range_type& cols() const {return my_cols;}
 
 };
 
-} // namespace tbb 
+} // namespace tbb
 
 #endif /* __TBB_blocked_range3d_H */
index 896a28e6b02038e6795112a7d636c128160e4c5f..253ef7b2e767d00d31ee5ef66c4af57ef6219ca3 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_cache_aligned_allocator_H
@@ -31,6 +23,9 @@
 
 #include <new>
 #include "tbb_stddef.h"
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+ #include <utility> // std::forward
+#endif
 
 namespace tbb {
 
@@ -99,7 +94,16 @@ public:
     }
 
     //! Copy-construct value at location pointed to by p.
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+    template<typename U, typename... Args>
+    void construct(U *p, Args&&... args)
+        { ::new((void *)p) U(std::forward<Args>(args)...); }
+#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));}
+#endif
     void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
+#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
 
     //! Destroy value at location pointed to by p.
     void destroy( pointer p ) {p->~value_type();}
index 8b3bdef7b822ee4dc8aa43278400cd10d730e8b6..566606d6f1168c5bd723d59fd6f814b0dd9ebdf7 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_combinable_H
index c73f521a192a8919a918f6c5a2438d01a918af4c..89c2ccf55397d67e56d125dbb670c7975378726b 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_condition_variable_H
@@ -410,6 +402,11 @@ inline cv_status condition_variable::wait_for( unique_lock<mutex>& lock, const t
     req.tv_sec  = tv.tv_sec + static_cast<long>(sec);
     req.tv_nsec = tv.tv_usec*1000 + static_cast<long>( (sec - static_cast<long>(sec))*1e9 );
 #endif /*(choice of OS) */
+    if( req.tv_nsec>=1e9 ) {
+        req.tv_sec  += 1;
+        req.tv_nsec -= static_cast<long int>(1e9);
+    }
+    __TBB_ASSERT( 0<=req.tv_nsec && req.tv_nsec<1e9, NULL );
 
     int ec;
     cv_status rc = no_timeout;
index 6f93148c2adfda7ffaba7b1c4b99b2a0e74b8e1c..9012e0acd9cee721c4cc9c2df16bc379ba2fd04f 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_compat_ppl_H
index c4884ec7d8abca6a3710da41d74ecedd421b8c44..64197bfc0f9f1d341c61ac65133009e7e2faf27b 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_thread_H
index 3177a14a252b9837343ec994aa0bfe948778e552..00b7809cad60f4e940b995557021e2a9a14f5e30 100644 (file)
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tuple_H
 #define __TBB_tuple_H
 
-#if !TBB_PREVIEW_TUPLE
-#error Set TBB_PREVIEW_TUPLE to include compat/tuple
-#endif
-
 #include <utility>
 #include "../tbb_stddef.h"
 
+// build preprocessor variables for varying number of arguments
+// Need the leading comma so the empty __TBB_T_PACK will not cause a syntax error.
+#if __TBB_VARIADIC_MAX <= 5
+#define __TBB_T_PACK
+#define __TBB_U_PACK
+#define __TBB_TYPENAME_T_PACK
+#define __TBB_TYPENAME_U_PACK
+#define __TBB_NULL_TYPE_PACK
+#define __TBB_REF_T_PARAM_PACK
+#define __TBB_CONST_REF_T_PARAM_PACK
+#define __TBB_T_PARAM_LIST_PACK
+#define __TBB_CONST_NULL_REF_PACK
+//
+#elif __TBB_VARIADIC_MAX == 6
+#define __TBB_T_PACK ,__T5
+#define __TBB_U_PACK ,__U5
+#define __TBB_TYPENAME_T_PACK , typename __T5
+#define __TBB_TYPENAME_U_PACK , typename __U5
+#define __TBB_NULL_TYPE_PACK , null_type
+#define __TBB_REF_T_PARAM_PACK ,__T5& t5
+#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5
+#define __TBB_T_PARAM_LIST_PACK ,t5
+#define __TBB_CONST_NULL_REF_PACK , const null_type&
+//
+#elif __TBB_VARIADIC_MAX == 7
+#define __TBB_T_PACK ,__T5, __T6
+#define __TBB_U_PACK ,__U5, __U6
+#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6
+#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6
+#define __TBB_NULL_TYPE_PACK , null_type, null_type
+#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6
+#define __TBB_CONST_REF_T_PARAM_PACK ,const __T5& t5, const __T6& t6
+#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6
+#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&
+//
+#elif __TBB_VARIADIC_MAX == 8
+#define __TBB_T_PACK ,__T5, __T6, __T7
+#define __TBB_U_PACK ,__U5, __U6, __U7
+#define __TBB_TYPENAME_T_PACK , typename __T5 , typename __T6, typename __T7
+#define __TBB_TYPENAME_U_PACK , typename __U5 , typename __U6, typename __U7
+#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type
+#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7
+#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7
+#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7
+#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&
+//
+#elif __TBB_VARIADIC_MAX == 9
+#define __TBB_T_PACK ,__T5, __T6, __T7, __T8
+#define __TBB_U_PACK ,__U5, __U6, __U7, __U8
+#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8
+#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8
+#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type
+#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8
+#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8
+#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8
+#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&
+//
+#elif __TBB_VARIADIC_MAX >= 10
+#define __TBB_T_PACK ,__T5, __T6, __T7, __T8, __T9
+#define __TBB_U_PACK ,__U5, __U6, __U7, __U8, __U9
+#define __TBB_TYPENAME_T_PACK , typename __T5, typename __T6, typename __T7, typename __T8, typename __T9
+#define __TBB_TYPENAME_U_PACK , typename __U5, typename __U6, typename __U7, typename __U8, typename __U9
+#define __TBB_NULL_TYPE_PACK , null_type, null_type, null_type, null_type, null_type
+#define __TBB_REF_T_PARAM_PACK ,__T5& t5, __T6& t6, __T7& t7, __T8& t8, __T9& t9
+#define __TBB_CONST_REF_T_PARAM_PACK , const __T5& t5, const __T6& t6, const __T7& t7, const __T8& t8, const __T9& t9
+#define __TBB_T_PARAM_LIST_PACK ,t5 ,t6 ,t7 ,t8 ,t9
+#define __TBB_CONST_NULL_REF_PACK , const null_type&, const null_type&, const null_type&, const null_type&, const null_type&
+#endif
+
+
+
 namespace tbb {
 namespace interface5 {
+
 namespace internal {
 struct null_type { };
 }
 using internal::null_type;
 
 // tuple forward declaration
-template <class T0=null_type, class T1=null_type, class T2=null_type, class T3=null_type, class T4=null_type, class T5=null_type, class T6=null_type, class T7=null_type, class T8=null_type, class T9=null_type>
+template <typename __T0=null_type, typename __T1=null_type, typename __T2=null_type,
+          typename __T3=null_type, typename __T4=null_type
+#if __TBB_VARIADIC_MAX >= 6
+, typename __T5=null_type
+#if __TBB_VARIADIC_MAX >= 7
+, typename __T6=null_type
+#if __TBB_VARIADIC_MAX >= 8
+, typename __T7=null_type
+#if __TBB_VARIADIC_MAX >= 9
+, typename __T8=null_type
+#if __TBB_VARIADIC_MAX >= 10
+, typename __T9=null_type
+#endif
+#endif
+#endif
+#endif
+#endif
+>
 class tuple;
 
 namespace internal {
@@ -53,18 +130,18 @@ namespace internal {
 inline const null_type cnull() { return null_type(); }
 
 // cons forward declaration
-template <class HT, class TT> struct cons;
+template <typename __HT, typename __TT> struct cons;
 
 // type of a component of the cons
-template<int N, class T>
+template<int __N, typename __T>
 struct component {
-    typedef typename T::tail_type next;
-    typedef typename component<N-1,next>::type type;
+    typedef typename __T::tail_type next;
+    typedef typename component<__N-1,next>::type type;
 };
 
-template<class T>
-struct component<0,T> {
-    typedef typename T::head_type type;
+template<typename __T>
+struct component<0,__T> {
+    typedef typename __T::head_type type;
 };
 
 template<>
@@ -74,63 +151,71 @@ struct component<0,null_type> {
 
 // const version of component
 
-template<int N, class T>
-struct component<N, const T>
+template<int __N, typename __T>
+struct component<__N, const __T>
 {
-    typedef typename T::tail_type next;
-    typedef typename component<N-1,next>::type type;
+    typedef typename __T::tail_type next;
+    typedef const typename component<__N-1,next>::type type;
 };
 
-template<class T>
-struct component<0, const T>
+template<typename __T>
+struct component<0, const __T>
 {
-    typedef const typename T::head_type type;
+    typedef const typename __T::head_type type;
 };
 
 
 // helper class for getting components of cons
-template< int N>
+template< int __N>
 struct get_helper {
-template<class HT, class TT>
-inline static typename component<N, cons<HT,TT> >::type& get(cons<HT,TT>& ti) {
-    return get_helper<N-1>::get(ti.tail);
+template<typename __HT, typename __TT>
+inline static typename component<__N, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) {
+    return get_helper<__N-1>::get(ti.tail);
+}
+template<typename __HT, typename __TT>
+inline static typename component<__N, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) {
+    return get_helper<__N-1>::get(ti.tail);
 }
 };
 
 template<>
 struct get_helper<0> {
-template<class HT, class TT>
-inline static typename component<0, cons<HT,TT> >::type& get(cons<HT,TT>& ti) {
+template<typename __HT, typename __TT>
+inline static typename component<0, cons<__HT,__TT> >::type& get(cons<__HT,__TT>& ti) {
+    return ti.head;
+}
+template<typename __HT, typename __TT>
+inline static typename component<0, cons<__HT,__TT> >::type const& get(const cons<__HT,__TT>& ti) {
     return ti.head;
 }
 };
 
 // traits adaptor
-template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
+template <typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK>
 struct tuple_traits {
-    typedef cons <T0, typename tuple_traits<T1, T2, T3, T4, T5, T6, T7, T8, T9, null_type>::U > U;
+    typedef cons <__T0, typename tuple_traits<__T1, __T2, __T3, __T4 __TBB_T_PACK , null_type>::U > U;
 };
 
-template <>
-struct tuple_traits<class T0, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> {
-    typedef cons<T0, null_type> U;
+template <typename __T0>
+struct tuple_traits<__T0, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > {
+    typedef cons<__T0, null_type> U;
 };
 
 template<>
-struct tuple_traits<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> {
+struct tuple_traits<null_type, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > {
     typedef null_type U;
 };
 
 
 // core cons defs
-template <class HT, class TT>
+template <typename __HT, typename __TT>
 struct cons{
 
-    typedef HT head_type;
-    typedef TT tail_type;
+    typedef __HT head_type;
+    typedef __TT tail_type;
 
-    HT head; 
-    TT tail;
+    head_type head; 
+    tail_type tail;
 
     static const int length = 1 + tail_type::length;
 
@@ -140,16 +225,16 @@ struct cons{
     // non-default constructors
     cons(head_type& h, const tail_type& t) : head(h), tail(t) { }
 
-    template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
-    cons(const T0& t0, const T1& t1, const T2& t2, const T3& t3, const T4& t4, const T5& t5, const T6& t6, const T7& t7, const T8& t8, const T9& t9) :
-        head(t0), tail(t1, t2, t3, t4, t5, t6, t7, t8, t9, cnull()) { }
+    template <typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
+    cons(const __T0& t0, const __T1& t1, const __T2& t2, const __T3& t3, const __T4& t4 __TBB_CONST_REF_T_PARAM_PACK) :
+        head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK, cnull()) { }
 
-    template <class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
-    cons(T0& t0, T1& t1, T2& t2, T3& t3, T4& t4, T5& t5, T6& t6, T7& t7, T8& t8, T9& t9) :
-        head(t0), tail(t1, t2, t3, t4, t5, t6, t7, t8, t9, cnull()) { }
+    template <typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
+    cons(__T0& t0, __T1& t1, __T2& t2, __T3& t3, __T4& t4 __TBB_REF_T_PARAM_PACK) :
+        head(t0), tail(t1, t2, t3, t4 __TBB_T_PARAM_LIST_PACK , cnull()) { }
 
-    template <class HT1, class TT1>
-    cons(const cons<HT1,TT1>& other) : head(other.head), tail(other.tail) { }
+    template <typename __HT1, typename __TT1>
+    cons(const cons<__HT1,__TT1>& other) : head(other.head), tail(other.tail) { }
 
     cons& operator=(const cons& other) { head = other.head; tail = other.tail; return *this; }
 
@@ -164,59 +249,61 @@ struct cons{
     friend bool operator>=(const cons& me, const cons& other) { return !(me<other); }
     friend bool operator<=(const cons& me, const cons& other) { return !(me>other); }
 
-    template<class HT1, class TT1>
-    friend bool operator==(const cons<HT,TT>& me, const cons<HT1,TT1>& other) {
+    template<typename __HT1, typename __TT1>
+    friend bool operator==(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) {
         return me.head == other.head && me.tail == other.tail;
     }
 
-    template<class HT1, class TT1>
-    friend bool operator<(const cons<HT,TT>& me, const cons<HT1,TT1>& other) {
+    template<typename __HT1, typename __TT1>
+    friend bool operator<(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) {
         return me.head < other.head || (!(other.head < me.head) && me.tail < other.tail);
     }
 
-    template<class HT1, class TT1>
-    friend bool operator>(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return other<me; }
+    template<typename __HT1, typename __TT1>
+    friend bool operator>(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return other<me; }
 
-    template<class HT1, class TT1>
-    friend bool operator!=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me==other); }
+    template<typename __HT1, typename __TT1>
+    friend bool operator!=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me==other); }
 
-    template<class HT1, class TT1>
-    friend bool operator>=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me<other); }
+    template<typename __HT1, typename __TT1>
+    friend bool operator>=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me<other); }
 
-    template<class HT1, class TT1>
-    friend bool operator<=(const cons<HT,TT>& me, const cons<HT1,TT1>& other) { return !(me>other); }
+    template<typename __HT1, typename __TT1>
+    friend bool operator<=(const cons<__HT,__TT>& me, const cons<__HT1,__TT1>& other) { return !(me>other); }
 
 
 };  // cons
 
 
-template <class HT>
-struct cons<HT,null_type> { 
+template <typename __HT>
+struct cons<__HT,null_type> { 
 
-    typedef HT head_type;
+    typedef __HT head_type;
     typedef null_type tail_type;
-    static const int length = 1;
+
     head_type head; 
 
+    static const int length = 1;
+
     // default constructor
     cons() : head() { /*std::cout << "default constructor 1\n";*/ }
 
-    cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head() { /*std::cout << "default constructor 2\n";*/ }
+    cons(const null_type&, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head() { /*std::cout << "default constructor 2\n";*/ }
 
     // non-default constructor
-    template<class T1>
-    cons(T1& t1, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type& ) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/}
+    template<typename __T1>
+    cons(__T1& t1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t1) { /*std::cout << "non-default a1, t1== " << t1 << "\n";*/}
 
     cons(head_type& h, const null_type& = null_type() ) : head(h) { }
-    cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head(t0) { }
+    cons(const head_type& t0, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(t0) { }
 
     // converting constructor
-    template<class HT1>
-    cons(HT1 h1, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&, const null_type&) : head(h1) { }
+    template<typename __HT1>
+    cons(__HT1 h1, const null_type&, const null_type&, const null_type&, const null_type& __TBB_CONST_NULL_REF_PACK) : head(h1) { }
 
     // copy constructor
-    template<class HT1>
-    cons( const cons<HT1, null_type>& other) : head(other.head) { }
+    template<typename __HT1>
+    cons( const cons<__HT1, null_type>& other) : head(other.head) { }
 
     // assignment operator
     cons& operator=(const cons& other) { head = other.head; return *this; }
@@ -228,27 +315,27 @@ struct cons<HT,null_type> {
     friend bool operator<=(const cons& me, const cons& other) {return !(me>other); }
     friend bool operator>=(const cons& me, const cons& other) {return !(me<other); }
 
-    template<class HT1>
-    friend bool operator==(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) {
+    template<typename __HT1>
+    friend bool operator==(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) {
         return me.head == other.head;
     }
 
-    template<class HT1>
-    friend bool operator<(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) {
+    template<typename __HT1>
+    friend bool operator<(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) {
         return me.head < other.head;
     }
 
-    template<class HT1>
-    friend bool operator>(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return other<me; }
+    template<typename __HT1>
+    friend bool operator>(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return other<me; }
 
-    template<class HT1>
-    friend bool operator!=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me==other); }
+    template<typename __HT1>
+    friend bool operator!=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me==other); }
 
-    template<class HT1>
-    friend bool operator<=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me>other); }
+    template<typename __HT1>
+    friend bool operator<=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me>other); }
 
-    template<class HT1>
-    friend bool operator>=(const cons<HT,null_type>& me, const cons<HT1,null_type>& other) { return !(me<other); }
+    template<typename __HT1>
+    friend bool operator>=(const cons<__HT,null_type>& me, const cons<__HT1,null_type>& other) { return !(me<other); }
 
 };  // cons
 
@@ -256,57 +343,71 @@ template <>
 struct cons<null_type,null_type> { typedef null_type tail_type; static const int length = 0; };
 
 // wrapper for default constructor
-template<class T>
-inline const T wrap_dcons(T*) { return T(); }
+template<typename __T>
+inline const __T wrap_dcons(__T*) { return __T(); }
+
 } // namespace internal
 
 // tuple definition
-template<class T0, class T1, class T2, class T3, class T4, class T5, class T6, class T7, class T8, class T9>
-class tuple : public internal::tuple_traits<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>::U {
+template<typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
+class tuple : public internal::tuple_traits<__T0, __T1, __T2, __T3, __T4 __TBB_T_PACK >::U {
     // friends
-    template <class T> friend class tuple_size;
-    template<int N, class T> friend struct tuple_element;
+    template <typename __T> friend class tuple_size;
+    template<int __N, typename __T> friend struct tuple_element;
 
     // stl components
-    typedef tuple<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9> value_type;
+    typedef tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > value_type;
     typedef value_type *pointer;
     typedef const value_type *const_pointer;
     typedef value_type &reference;
     typedef const value_type &const_reference;
     typedef size_t size_type;
 
-    typedef typename internal::tuple_traits<T0,T1,T2,T3, T4, T5, T6, T7, T8, T9>::U my_cons;
-public:
+    typedef typename internal::tuple_traits<__T0,__T1,__T2,__T3, __T4 __TBB_T_PACK >::U my_cons;
 
-    tuple(const T0& t0=internal::wrap_dcons((T0*)NULL),
-          const T1& t1=internal::wrap_dcons((T1*)NULL),
-          const T2& t2=internal::wrap_dcons((T2*)NULL),
-          const T3& t3=internal::wrap_dcons((T3*)NULL),
-          const T4& t4=internal::wrap_dcons((T4*)NULL),
-          const T5& t5=internal::wrap_dcons((T5*)NULL),
-          const T6& t6=internal::wrap_dcons((T6*)NULL),
-          const T7& t7=internal::wrap_dcons((T7*)NULL),
-          const T8& t8=internal::wrap_dcons((T8*)NULL),
-          const T9& t9=internal::wrap_dcons((T9*)NULL)
+public:
+    tuple(const __T0& t0=internal::wrap_dcons((__T0*)NULL)
+          ,const __T1& t1=internal::wrap_dcons((__T1*)NULL)
+          ,const __T2& t2=internal::wrap_dcons((__T2*)NULL)
+          ,const __T3& t3=internal::wrap_dcons((__T3*)NULL)
+          ,const __T4& t4=internal::wrap_dcons((__T4*)NULL)
+#if __TBB_VARIADIC_MAX >= 6
+          ,const __T5& t5=internal::wrap_dcons((__T5*)NULL)
+#if __TBB_VARIADIC_MAX >= 7
+          ,const __T6& t6=internal::wrap_dcons((__T6*)NULL)
+#if __TBB_VARIADIC_MAX >= 8
+          ,const __T7& t7=internal::wrap_dcons((__T7*)NULL)
+#if __TBB_VARIADIC_MAX >= 9
+          ,const __T8& t8=internal::wrap_dcons((__T8*)NULL)
+#if __TBB_VARIADIC_MAX >= 10
+          ,const __T9& t9=internal::wrap_dcons((__T9*)NULL)
+#endif
+#endif
+#endif
+#endif
+#endif
           ) :
-        internal::tuple_traits<T0,T1,T2,T3,T4,T5,T6,T7,T8,T9>::U(t0,t1,t2,t3,t4,t5,t6,t7,t8,t9) { }
+        my_cons(t0,t1,t2,t3,t4 __TBB_T_PARAM_LIST_PACK) { }
 
-    template<int N>
+    template<int __N>
     struct internal_tuple_element {
-        typedef typename internal::component<N,my_cons>::type type;
+        typedef typename internal::component<__N,my_cons>::type type;
     };
 
-    template<int N>
-    typename internal_tuple_element<N>::type& get() { return internal::get_helper<N>::get(*this); }
+    template<int __N>
+    typename internal_tuple_element<__N>::type& get() { return internal::get_helper<__N>::get(*this); }
 
-    template<class U1, class U2>
-    tuple& operator=(const internal::cons<U1,U2>& other) {
+    template<int __N>
+    typename internal_tuple_element<__N>::type const& get() const { return internal::get_helper<__N>::get(*this); }
+
+    template<typename __U1, typename __U2>
+    tuple& operator=(const internal::cons<__U1,__U2>& other) {
         my_cons::operator=(other);
         return *this;
     }
 
-    template<class U1, class U2>
-    tuple& operator=(const std::pair<U1,U2>& other) {
+    template<typename __U1, typename __U2>
+    tuple& operator=(const std::pair<__U1,__U2>& other) {
         // __TBB_ASSERT(tuple_size<value_type>::value == 2, "Invalid size for pair to tuple assignment");
         this->head = other.first;
         this->tail.head = other.second;
@@ -320,50 +421,19 @@ public:
     friend bool operator>=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)>=(other);}
     friend bool operator<=(const tuple& me, const tuple& other) {return static_cast<const my_cons &>(me)<=(other);}
 
-    template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
-    friend bool operator==(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
-        return static_cast<const my_cons &>(me)==(other);
-    }
-
-    template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
-    friend bool operator<(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
-        return static_cast<const my_cons &>(me)<(other);
-    }
-
-    template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
-    friend bool operator>(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
-        return static_cast<const my_cons &>(me)>(other);
-    }
-
-    template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
-    friend bool operator!=(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
-        return static_cast<const my_cons &>(me)!=(other);
-    }
-
-    template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
-    friend bool operator>=(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
-        return static_cast<const my_cons &>(me)>=(other);
-    }
-
-    template<class U0, class U1, class U2, class U3, class U4, class U5, class U6, class U7, class U8, class U9>
-    friend bool operator<=(const tuple& me, const tuple<U0,U1,U2,U3,U4,U5,U6,U7,U8,U9>& other) {
-        return static_cast<const my_cons &>(me)<=(other);
-    }
-
 };  // tuple
 
 // empty tuple
 template<>
-class tuple<null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type, null_type> : public null_type {
-    typedef null_type inherited;
+class tuple<null_type, null_type, null_type, null_type, null_type __TBB_NULL_TYPE_PACK > : public null_type {
 };
 
 // helper classes
 
-template < class T>
+template < typename __T>
 class tuple_size {
 public:
-    static const size_t value = 1 + tuple_size<typename T::tail_type>::value;
+    static const size_t value = 1 + tuple_size<typename __T::tail_type>::value;
 };
 
 template <>
@@ -378,29 +448,41 @@ public:
     static const size_t value = 0;
 };
 
-template<int N, class T>
+template<int __N, typename __T>
 struct tuple_element {
-    typedef typename internal::component<N, typename T::my_cons>::type type;
+    typedef typename internal::component<__N, typename __T::my_cons>::type type;
 };
 
-template<int N, class T>
-inline static typename tuple_element<N,T>::type& get(T &t) { return t.get<N>(); }
+template<int __N, typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
+inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type&
+    get(tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); }
 
-template<int N, class T>
-inline static typename tuple_element<N,T>::type const& get(T const &t) { return 
-    const_cast<typename tuple_element<N,T>::type const &>
-        (const_cast<T &>(t).get<N>()); }
+template<int __N, typename __T0, typename __T1, typename __T2, typename __T3, typename __T4 __TBB_TYPENAME_T_PACK >
+inline static typename tuple_element<__N,tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK > >::type const&
+    get(const tuple<__T0,__T1,__T2,__T3,__T4 __TBB_T_PACK >& t) { return internal::get_helper<__N>::get(t); }
 
 }  // interface5
 } // tbb
 
-#if TBB_IMPLEMENT_CPP0X
-namespace std {
-using tbb::interface5::tuple;
-using tbb::interface5::tuple_size;
-using tbb::interface5::tuple_element;
-using tbb::interface5::get;
+#if !__TBB_CPP11_TUPLE_PRESENT
+namespace tbb {
+    namespace flow {
+        using tbb::interface5::tuple;
+        using tbb::interface5::tuple_size;
+        using tbb::interface5::tuple_element;
+        using tbb::interface5::get;
+    }
 }
 #endif
+
+#undef __TBB_T_PACK
+#undef __TBB_U_PACK
+#undef __TBB_TYPENAME_T_PACK
+#undef __TBB_TYPENAME_U_PACK
+#undef __TBB_NULL_TYPE_PACK
+#undef __TBB_REF_T_PARAM_PACK
+#undef __TBB_CONST_REF_T_PARAM_PACK
+#undef __TBB_T_PARAM_LIST_PACK
+#undef __TBB_CONST_NULL_REF_PACK
  
 #endif /* __TBB_tuple_H */
index ce589c93cd73111c492c01655197ecc31ea3a1f1..a635899daf6b2188bc836ff36e7d7164df357a10 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_concurrent_hash_map_H
@@ -40,6 +32,7 @@
 #include <iterator>
 #include <utility>      // Need std::pair
 #include <cstring>      // Need std::memset
+#include <algorithm>    // Need std::swap
 
 #if !TBB_USE_EXCEPTIONS && _MSC_VER
     #pragma warning (pop)
 #include "tbb_allocator.h"
 #include "spin_rw_mutex.h"
 #include "atomic.h"
-#include "aligned_space.h"
 #include "tbb_exception.h"
 #include "tbb_profiling.h"
 #include "internal/_concurrent_unordered_impl.h" // Need tbb_hasher
+#if __TBB_INITIALIZER_LISTS_PRESENT
+#include <initializer_list>
+#endif
 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
 #include <typeinfo>
 #endif
@@ -76,6 +71,7 @@ namespace interface5 {
 
     //! @cond INTERNAL
     namespace internal {
+    using namespace tbb::internal;
 
 
     //! Type of a hash code.
@@ -169,21 +165,21 @@ namespace interface5 {
         static size_type segment_size( segment_index_t k ) {
             return size_type(1)<<k; // fake value for k==0
         }
-        
+
         //! @return true if @arg ptr is valid pointer
         static bool is_valid( void *ptr ) {
-            return reinterpret_cast<size_t>(ptr) > size_t(63);
+            return reinterpret_cast<uintptr_t>(ptr) > uintptr_t(63);
         }
 
         //! Initialize buckets
         static void init_buckets( segment_ptr_t ptr, size_type sz, bool is_initial ) {
             if( is_initial ) std::memset(ptr, 0, sz*sizeof(bucket) );
             else for(size_type i = 0; i < sz; i++, ptr++) {
-                    *reinterpret_cast<intptr_t*>(&ptr->mutex) = 0;
-                    ptr->node_list = rehash_req;
-                }
+                *reinterpret_cast<intptr_t*>(&ptr->mutex) = 0;
+                ptr->node_list = rehash_req;
+            }
         }
-        
+
         //! Add node @arg n to bucket @arg b
         static void add_to_bucket( bucket *b, node_base *n ) {
             __TBB_ASSERT(b->node_list != rehash_req, NULL);
@@ -192,7 +188,7 @@ namespace interface5 {
         }
 
         //! Exception safety helper
-        struct enable_segment_failsafe {
+        struct enable_segment_failsafe : tbb::internal::no_copy {
             segment_ptr_t *my_segment_ptr;
             enable_segment_failsafe(segments_table_t &table, segment_index_t k) : my_segment_ptr(&table[k]) {}
             ~enable_segment_failsafe() {
@@ -282,11 +278,12 @@ namespace interface5 {
             size_type sz = ++my_size; // prefix form is to enforce allocation after the first item inserted
             add_to_bucket( b, n );
             // check load factor
-            if( sz >= mask ) { // TODO: add custom load_factor 
+            if( sz >= mask ) { // TODO: add custom load_factor
                 segment_index_t new_seg = __TBB_Log2( mask+1 ); //optimized segment_index_of
                 __TBB_ASSERT( is_valid(my_table[new_seg-1]), "new allocations must not publish new mask until segment has allocated");
+                static const segment_ptr_t is_allocating = (segment_ptr_t)2;
                 if( !itt_hide_load_word(my_table[new_seg])
-                  && __TBB_CompareAndSwapW(&my_table[new_seg], 2, 0) == 0 )
+                  && as_atomic(my_table[new_seg]).compare_and_swap(is_allocating, NULL) == NULL )
                     return new_seg; // The value must be processed
             }
             return 0;
@@ -301,12 +298,13 @@ namespace interface5 {
         }
         //! Swap hash_map_bases
         void internal_swap(hash_map_base &table) {
-            std::swap(this->my_mask, table.my_mask);
-            std::swap(this->my_size, table.my_size);
+            using std::swap;
+            swap(this->my_mask, table.my_mask);
+            swap(this->my_size, table.my_size);
             for(size_type i = 0; i < embedded_buckets; i++)
-                std::swap(this->my_embedded_segment[i].node_list, table.my_embedded_segment[i].node_list);
+                swap(this->my_embedded_segment[i].node_list, table.my_embedded_segment[i].node_list);
             for(size_type i = embedded_block; i < pointers_per_table; i++)
-                std::swap(this->my_table[i], table.my_table[i]);
+                swap(this->my_table[i], table.my_table[i]);
         }
     };
 
@@ -315,7 +313,7 @@ namespace interface5 {
 
     //! Meets requirements of a forward iterator for STL */
     /** Value is either the T or const T type of the container.
-        @ingroup containers */ 
+        @ingroup containers */
     template<typename Container, typename Value>
     class hash_map_iterator
         : public std::iterator<std::forward_iterator_tag,Value>
@@ -333,7 +331,7 @@ namespace interface5 {
 
         template<typename C, typename T, typename U>
         friend ptrdiff_t operator-( const hash_map_iterator<C,T>& i, const hash_map_iterator<C,U>& j );
-    
+
         template<typename C, typename U>
         friend class hash_map_iterator;
 
@@ -390,7 +388,7 @@ namespace interface5 {
         }
         Value* operator->() const {return &operator*();}
         hash_map_iterator& operator++();
-        
+
         //! Post increment
         hash_map_iterator operator++(int) {
             hash_map_iterator old(*this);
@@ -428,7 +426,7 @@ namespace interface5 {
     }
 
     //! Range class used with concurrent_hash_map
-    /** @ingroup containers */ 
+    /** @ingroup containers */
     template<typename Iterator>
     class hash_map_range {
         typedef typename Iterator::map_type map_type;
@@ -455,7 +453,7 @@ namespace interface5 {
             return my_midpoint!=my_end;
         }
         //! Split range.
-        hash_map_range( hash_map_range& r, split ) : 
+        hash_map_range( hash_map_range& r, split ) :
             my_end(r.my_end),
             my_grainsize(r.my_grainsize)
         {
@@ -467,27 +465,14 @@ namespace interface5 {
         }
         //! type conversion
         template<typename U>
-        hash_map_range( hash_map_range<U>& r) : 
+        hash_map_range( hash_map_range<U>& r) :
             my_begin(r.my_begin),
             my_end(r.my_end),
             my_midpoint(r.my_midpoint),
             my_grainsize(r.my_grainsize)
         {}
-#if TBB_DEPRECATED
-        //! Init range with iterators and grainsize specified
-        hash_map_range( const Iterator& begin_, const Iterator& end_, size_type grainsize_ = 1 ) : 
-            my_begin(begin_), 
-            my_end(end_),
-            my_grainsize(grainsize_)
-        {
-            if(!my_end.my_index && !my_end.my_bucket) // end
-                my_end.my_index = my_end.my_map->my_mask + 1;
-            set_midpoint();
-            __TBB_ASSERT( grainsize_>0, "grainsize must be positive" );
-        }
-#endif
         //! Init range with container and grainsize specified
-        hash_map_range( const map_type &map, size_type grainsize_ = 1 ) : 
+        hash_map_range( const map_type &map, size_type grainsize_ = 1 ) :
             my_begin( Iterator( map, 0, map.my_embedded_segment, map.my_embedded_segment->node_list ) ),
             my_end( Iterator( map, map.my_mask + 1, 0, 0 ) ),
             my_grainsize( grainsize_ )
@@ -523,6 +508,12 @@ namespace interface5 {
     } // internal
 //! @endcond
 
+#if _MSC_VER && !defined(__INTEL_COMPILER)
+    // Suppress "conditional expression is constant" warning.
+    #pragma warning( push )
+    #pragma warning( disable: 4127 )
+#endif
+
 //! Unordered map from Key to T.
 /** concurrent_hash_map is associative container with concurrent access.
 
@@ -550,7 +541,7 @@ namespace interface5 {
     - Added overloaded erase(accessor &) and erase(const_accessor&)
     - Added equal_range() [const]
     - Added [const_]pointer, [const_]reference, and allocator_type types
-    - Added global functions: operator==(), operator!=(), and swap() 
+    - Added global functions: operator==(), operator!=(), and swap()
 
     @ingroup containers */
 template<typename Key, typename T, typename HashCompare, typename Allocator>
@@ -588,15 +579,20 @@ protected:
         value_type item;
         node( const Key &key ) : item(key, T()) {}
         node( const Key &key, const T &t ) : item(key, t) {}
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+        node( value_type&& i ) : item(std::move(i)){}
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+        node( const value_type& i ) : item(i) {}
+
         // exception-safe allocation, see C++ Standard 2003, clause 5.3.4p17
         void *operator new( size_t /*size*/, node_allocator_type &a ) {
             void *ptr = a.allocate(1);
-            if(!ptr) 
+            if(!ptr)
                 tbb::internal::throw_exception(tbb::internal::eid_bad_alloc);
             return ptr;
         }
         // match placement-new form above to be called if exception thrown in constructor
-        void operator delete( void *ptr, node_allocator_type &a ) {return a.deallocate(static_cast<node*>(ptr),1); }
+        void operator delete( void *ptr, node_allocator_type &a ) { a.deallocate(static_cast<node*>(ptr),1); }
     };
 
     void delete_node( node_base *n ) {
@@ -604,6 +600,19 @@ protected:
         my_allocator.deallocate( static_cast<node*>(n), 1);
     }
 
+    static node* allocate_node_copy_construct(node_allocator_type& allocator, const Key &key, const T * t){
+        return  new( allocator ) node(key, *t);
+    }
+
+    static node* allocate_node_default_construct(node_allocator_type& allocator, const Key &key, const T * ){
+        return  new( allocator ) node(key);
+    }
+
+    static node* do_not_allocate_node(node_allocator_type& , const Key &, const T * ){
+        __TBB_ASSERT(false,"this dummy function should not be called");
+        return NULL;
+    }
+
     node *search_bucket( const key_type &key, bucket *b ) const {
         node *n = static_cast<node*>( b->node_list );
         while( is_valid(n) && !my_hash_compare.equal(key, n->item.first) )
@@ -668,8 +677,18 @@ protected:
         }
     }
 
+    struct call_clear_on_leave {
+        concurrent_hash_map* my_ch_map;
+        call_clear_on_leave( concurrent_hash_map* a_ch_map ) : my_ch_map(a_ch_map) {}
+        void dismiss() {my_ch_map = 0;}
+        ~call_clear_on_leave(){
+            if (my_ch_map){
+                my_ch_map->clear();
+            }
+        }
+    };
 public:
-    
+
     class accessor;
     //! Combines data access, locking, and garbage collection.
     class const_accessor : private node::scoped_t /*which derived from no_copy*/ {
@@ -680,7 +699,7 @@ public:
         typedef const typename concurrent_hash_map::value_type value_type;
 
         //! True if result is empty.
-        bool empty() const {return !my_node;}
+        bool empty() const { return !my_node; }
 
         //! Set to null
         void release() {
@@ -733,52 +752,114 @@ public:
     };
 
     //! Construct empty table.
-    concurrent_hash_map(const allocator_type &a = allocator_type())
+    concurrent_hash_map( const allocator_type &a = allocator_type() )
         : internal::hash_map_base(), my_allocator(a)
     {}
 
     //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level.
-    concurrent_hash_map(size_type n, const allocator_type &a = allocator_type())
+    concurrent_hash_map( size_type n, const allocator_type &a = allocator_type() )
         : my_allocator(a)
     {
         reserve( n );
     }
 
     //! Copy constructor
-    concurrent_hash_map( const concurrent_hash_map& table, const allocator_type &a = allocator_type())
+    concurrent_hash_map( const concurrent_hash_map &table, const allocator_type &a = allocator_type() )
         : internal::hash_map_base(), my_allocator(a)
     {
         internal_copy(table);
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move constructor
+    concurrent_hash_map( concurrent_hash_map &&table )
+        : internal::hash_map_base(), my_allocator(std::move(table.get_allocator()))
+    {
+        swap(table);
+    }
+
+    //! Move constructor 
+    concurrent_hash_map( concurrent_hash_map &&table, const allocator_type &a )
+        : internal::hash_map_base(), my_allocator(a)
+    {
+        if (a == table.get_allocator()){
+            this->swap(table);
+        }else{
+            call_clear_on_leave scope_guard(this);
+            internal_copy(std::make_move_iterator(table.begin()), std::make_move_iterator(table.end()));
+            scope_guard.dismiss();
+        }
+    }
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
     //! Construction with copying iteration range and given allocator instance
     template<typename I>
-    concurrent_hash_map(I first, I last, const allocator_type &a = allocator_type())
+    concurrent_hash_map( I first, I last, const allocator_type &a = allocator_type() )
         : my_allocator(a)
     {
         reserve( std::distance(first, last) ); // TODO: load_factor?
         internal_copy(first, last);
     }
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Construct empty table with n preallocated buckets. This number serves also as initial concurrency level.
+    concurrent_hash_map( std::initializer_list<value_type> il, const allocator_type &a = allocator_type() )
+        : my_allocator(a)
+    {
+        reserve(il.size());
+        internal_copy(il.begin(), il.end());
+    }
+
+#endif //__TBB_INITIALIZER_LISTS_PRESENT
+
     //! Assignment
-    concurrent_hash_map& operator=( const concurrent_hash_maptable ) {
+    concurrent_hash_map& operator=( const concurrent_hash_map &table ) {
         if( this!=&table ) {
             clear();
             internal_copy(table);
-        } 
+        }
         return *this;
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move Assignment
+    concurrent_hash_map& operator=( concurrent_hash_map &&table ) {
+        if(this != &table){
+            typedef typename tbb::internal::allocator_traits<allocator_type>::propagate_on_container_move_assignment pocma_t;
+            if(pocma_t::value || this->my_allocator == table.my_allocator) {
+                concurrent_hash_map trash (std::move(*this));
+                //TODO: swapping allocators here may be a problem, replace with single direction moving iff pocma is set
+                this->swap(table);
+            } else {
+                //do per element move
+                concurrent_hash_map moved_copy(std::move(table), this->my_allocator);
+                this->swap(moved_copy);
+            }
+        }
+        return *this;
+    }
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Assignment
+    concurrent_hash_map& operator=( std::initializer_list<value_type> il ) {
+        clear();
+        reserve(il.size());
+        internal_copy(il.begin(), il.end());
+        return *this;
+    }
+#endif //__TBB_INITIALIZER_LISTS_PRESENT
+
 
     //! Rehashes and optionally resizes the whole table.
     /** Useful to optimize performance before or after concurrent operations.
         Also enables using of find() and count() concurrent methods in serial context. */
     void rehash(size_type n = 0);
-    
+
     //! Clear table
     void clear();
 
-    //! Clear table and destroy it.  
+    //! Clear table and destroy it.
     ~concurrent_hash_map() { clear(); }
 
     //------------------------------------------------------------------------
@@ -794,13 +875,13 @@ public:
     //------------------------------------------------------------------------
     // STL support - not thread-safe methods
     //------------------------------------------------------------------------
-    iterator begin() {return iterator(*this,0,my_embedded_segment,my_embedded_segment->node_list);}
-    iterator end() {return iterator(*this,0,0,0);}
-    const_iterator begin() const {return const_iterator(*this,0,my_embedded_segment,my_embedded_segment->node_list);}
-    const_iterator end() const {return const_iterator(*this,0,0,0);}
-    std::pair<iterator, iterator> equal_range( const Key& key ) { return internal_equal_range(key, end()); }
-    std::pair<const_iterator, const_iterator> equal_range( const Key& key ) const { return internal_equal_range(key, end()); }
-    
+    iterator begin() { return iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); }
+    iterator end() { return iterator( *this, 0, 0, 0 ); }
+    const_iterator begin() const { return const_iterator( *this, 0, my_embedded_segment, my_embedded_segment->node_list ); }
+    const_iterator end() const { return const_iterator( *this, 0, 0, 0 ); }
+    std::pair<iterator, iterator> equal_range( const Key& key ) { return internal_equal_range( key, end() ); }
+    std::pair<const_iterator, const_iterator> equal_range( const Key& key ) const { return internal_equal_range( key, end() ); }
+
     //! Number of items in table.
     size_type size() const { return my_size; }
 
@@ -817,7 +898,7 @@ public:
     allocator_type get_allocator() const { return this->my_allocator; }
 
     //! swap two instances. Iterators are invalidated
-    void swap(concurrent_hash_map &table);
+    void swap( concurrent_hash_map &table );
 
     //------------------------------------------------------------------------
     // concurrent map operations
@@ -825,64 +906,71 @@ public:
 
     //! Return count of items (0 or 1)
     size_type count( const Key &key ) const {
-        return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false );
+        return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, NULL, /*write=*/false, &do_not_allocate_node );
     }
 
     //! Find item and acquire a read lock on the item.
     /** Return true if item is found, false otherwise. */
     bool find( const_accessor &result, const Key &key ) const {
         result.release();
-        return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false );
+        return const_cast<concurrent_hash_map*>(this)->lookup(/*insert*/false, key, NULL, &result, /*write=*/false, &do_not_allocate_node );
     }
 
     //! Find item and acquire a write lock on the item.
     /** Return true if item is found, false otherwise. */
     bool find( accessor &result, const Key &key ) {
         result.release();
-        return lookup(/*insert*/false, key, NULL, &result, /*write=*/true );
+        return lookup(/*insert*/false, key, NULL, &result, /*write=*/true, &do_not_allocate_node );
     }
-        
+
     //! Insert item (if not already present) and acquire a read lock on the item.
     /** Returns true if item is new. */
     bool insert( const_accessor &result, const Key &key ) {
         result.release();
-        return lookup(/*insert*/true, key, NULL, &result, /*write=*/false );
+        return lookup(/*insert*/true, key, NULL, &result, /*write=*/false, &allocate_node_default_construct );
     }
 
     //! Insert item (if not already present) and acquire a write lock on the item.
     /** Returns true if item is new. */
     bool insert( accessor &result, const Key &key ) {
         result.release();
-        return lookup(/*insert*/true, key, NULL, &result, /*write=*/true );
+        return lookup(/*insert*/true, key, NULL, &result, /*write=*/true, &allocate_node_default_construct );
     }
 
     //! Insert item by copying if there is no such key present already and acquire a read lock on the item.
     /** Returns true if item is new. */
     bool insert( const_accessor &result, const value_type &value ) {
         result.release();
-        return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false );
+        return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/false, &allocate_node_copy_construct );
     }
 
     //! Insert item by copying if there is no such key present already and acquire a write lock on the item.
     /** Returns true if item is new. */
     bool insert( accessor &result, const value_type &value ) {
         result.release();
-        return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true );
+        return lookup(/*insert*/true, value.first, &value.second, &result, /*write=*/true, &allocate_node_copy_construct );
     }
 
     //! Insert item by copying if there is no such key present already
     /** Returns true if item is inserted. */
     bool insert( const value_type &value ) {
-        return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false );
+        return lookup(/*insert*/true, value.first, &value.second, NULL, /*write=*/false, &allocate_node_copy_construct );
     }
 
     //! Insert range [first, last)
     template<typename I>
-    void insert(I first, I last) {
-        for(; first != last; ++first)
+    void insert( I first, I last ) {
+        for ( ; first != last; ++first )
             insert( *first );
     }
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Insert initializer list
+    void insert( std::initializer_list<value_type> il ) {
+        insert( il.begin(), il.end() );
+    }
+#endif //__TBB_INITIALIZER_LISTS_PRESENT
+
     //! Erase item.
     /** Return true if item was erased by particularly this call. */
     bool erase( const Key& key );
@@ -901,7 +989,7 @@ public:
 
 protected:
     //! Insert or find item and optionally acquire a lock on the item.
-    bool lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write );
+    bool lookup(bool op_insert, const Key &key, const T *t, const_accessor *result, bool write,  node* (*allocate_node)(node_allocator_type& ,  const Key &, const T * )  ) ;
 
     //! delete item by accessor
     bool exclude( const_accessor &item_accessor );
@@ -914,7 +1002,7 @@ protected:
     void internal_copy( const concurrent_hash_map& source );
 
     template<typename I>
-    void internal_copy(I first, I last);
+    void internal_copy( I first, I last );
 
     //! Fast find when no concurrent erasure is used. For internal use inside TBB only!
     /** Return pointer to item with given key, or NULL if no such item exists.
@@ -924,7 +1012,7 @@ protected:
         hashcode_t m = (hashcode_t) itt_load_word_with_acquire( my_mask );
         node *n;
     restart:
-        __TBB_ASSERT((m&(m+1))==0, NULL);
+        __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
         bucket *b = get_bucket( h & m );
         // TODO: actually, notification is unnecessary here, just hiding double-check
         if( itt_load_word_with_acquire(b->node_list) == internal::rehash_req )
@@ -946,14 +1034,8 @@ protected:
     }
 };
 
-#if _MSC_VER && !defined(__INTEL_COMPILER)
-    // Suppress "conditional expression is constant" warning.
-    #pragma warning( push )
-    #pragma warning( disable: 4127 )
-#endif
-
 template<typename Key, typename T, typename HashCompare, typename A>
-bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write ) {
+bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key &key, const T *t, const_accessor *result, bool write, node* (*allocate_node)(node_allocator_type& , const Key&, const T*) ) {
     __TBB_ASSERT( !result || !result->my_node, NULL );
     bool return_value;
     hashcode_t const h = my_hash_compare.hash( key );
@@ -962,7 +1044,7 @@ bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key
     node *n, *tmp_n = 0;
     restart:
     {//lock scope
-        __TBB_ASSERT((m&(m+1))==0, NULL);
+        __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
         return_value = false;
         // get bucket
         bucket_accessor b( this, h & m );
@@ -973,8 +1055,7 @@ bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key
             // [opt] insert a key
             if( !n ) {
                 if( !tmp_n ) {
-                    if(t) tmp_n = new( my_allocator ) node(key, *t);
-                    else  tmp_n = new( my_allocator ) node(key);
+                    tmp_n = allocate_node(my_allocator, key, t);
                 }
                 if( !b.is_writer() && !b.upgrade_to_writer() ) { // TODO: improved insertion
                     // Rerun search_list, in case another thread inserted the item during the upgrade.
@@ -1004,10 +1085,9 @@ bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key
         // TODO: the following seems as generic/regular operation
         // acquire the item
         if( !result->try_acquire( n->mutex, write ) ) {
-            // we are unlucky, prepare for longer wait
-            tbb::internal::atomic_backoff trials;
-            do {
-                if( !trials.bounded_pause() ) {
+            for( tbb::internal::atomic_backoff backoff(true);; ) {
+                if( result->try_acquire( n->mutex, write ) ) break;
+                if( !backoff.bounded_pause() ) {
                     // the wait takes really long, restart the operation
                     b.release();
                     __TBB_ASSERT( !op_insert || !return_value, "Can't acquire new item in locked bucket?" );
@@ -1015,7 +1095,7 @@ bool concurrent_hash_map<Key,T,HashCompare,A>::lookup( bool op_insert, const Key
                     m = (hashcode_t) itt_load_word_with_acquire( my_mask );
                     goto restart;
                 }
-            } while( !result->try_acquire( n->mutex, write ) );
+            }
         }
     }//lock scope
     result->my_node = n;
@@ -1038,7 +1118,7 @@ template<typename I>
 std::pair<I, I> concurrent_hash_map<Key,T,HashCompare,A>::internal_equal_range( const Key& key, I end_ ) const {
     hashcode_t h = my_hash_compare.hash( key );
     hashcode_t m = my_mask;
-    __TBB_ASSERT((m&(m+1))==0, NULL);
+    __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
     h &= m;
     bucket *b = get_bucket( h );
     while( b->node_list == internal::rehash_req ) {
@@ -1064,7 +1144,7 @@ bool concurrent_hash_map<Key,T,HashCompare,A>::exclude( const_accessor &item_acc
         node_base **p = &b()->node_list;
         while( *p && *p != n )
             p = &(*p)->next;
-        if( !*p ) { // someone else was the first
+        if( !*p ) { // someone else was first
             if( check_mask_race( h, m ) )
                 continue;
             item_accessor.release();
@@ -1121,8 +1201,10 @@ restart:
 
 template<typename Key, typename T, typename HashCompare, typename A>
 void concurrent_hash_map<Key,T,HashCompare,A>::swap(concurrent_hash_map<Key,T,HashCompare,A> &table) {
-    std::swap(this->my_allocator, table.my_allocator);
-    std::swap(this->my_hash_compare, table.my_hash_compare);
+    //TODO: respect C++11 allocator_traits<A>::propogate_on_constainer_swap
+    using std::swap;
+    swap(this->my_allocator, table.my_allocator);
+    swap(this->my_hash_compare, table.my_hash_compare);
     internal_swap(table);
 }
 
@@ -1131,7 +1213,7 @@ void concurrent_hash_map<Key,T,HashCompare,A>::rehash(size_type sz) {
     reserve( sz ); // TODO: add reduction of number of buckets as well
     hashcode_t mask = my_mask;
     hashcode_t b = (mask+1)>>1; // size or first index of the last segment
-    __TBB_ASSERT((b&(b-1))==0, NULL);
+    __TBB_ASSERT((b&(b-1))==0, NULL); // zero or power of 2
     bucket *bp = get_bucket( b ); // only the last segment should be scanned for rehashing
     for(; b <= mask; b++, bp++ ) {
         node_base *n = bp->node_list;
@@ -1195,7 +1277,7 @@ void concurrent_hash_map<Key,T,HashCompare,A>::rehash(size_type sz) {
 template<typename Key, typename T, typename HashCompare, typename A>
 void concurrent_hash_map<Key,T,HashCompare,A>::clear() {
     hashcode_t m = my_mask;
-    __TBB_ASSERT((m&(m+1))==0, NULL);
+    __TBB_ASSERT((m&(m+1))==0, "data structure is invalid");
 #if TBB_USE_ASSERT || TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
 #if TBB_USE_PERFORMANCE_WARNINGS || __TBB_STATISTICS
     int current_size = int(my_size), buckets = int(m)+1, empty_buckets = 0, overpopulated_buckets = 0; // usage statistics
@@ -1293,10 +1375,10 @@ template<typename I>
 void concurrent_hash_map<Key,T,HashCompare,A>::internal_copy(I first, I last) {
     hashcode_t m = my_mask;
     for(; first != last; ++first) {
-        hashcode_t h = my_hash_compare.hash( first->first );
+        hashcode_t h = my_hash_compare.hash( (*first).first );
         bucket *b = get_bucket( h & m );
         __TBB_ASSERT( b->node_list != internal::rehash_req, "Invalid bucket in destination table");
-        node *n = new( my_allocator ) node(first->first, first->second);
+        node *n = new( my_allocator ) node(*first);
         add_to_bucket( b, n );
         ++my_size; // TODO: replace by non-atomic op
     }
diff --git a/dependencies64/tbb/include/tbb/concurrent_lru_cache.h b/dependencies64/tbb/include/tbb/concurrent_lru_cache.h
new file mode 100644 (file)
index 0000000..dbf0f1f
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_concurrent_lru_cache_H
+#define __TBB_concurrent_lru_cache_H
+
+#if ! TBB_PREVIEW_CONCURRENT_LRU_CACHE
+    #error Set TBB_PREVIEW_CONCURRENT_LRU_CACHE to include concurrent_lru_cache.h
+#endif
+
+#include <map>
+#include <list>
+
+#include "tbb_stddef.h"
+#include "atomic.h"
+#include "internal/_aggregator_impl.h"
+
+namespace tbb{
+namespace interface6 {
+
+
+template <typename key_type, typename value_type, typename value_functor_type = value_type (*)(key_type) >
+class concurrent_lru_cache : internal::no_assign{
+private:
+    typedef concurrent_lru_cache self_type;
+    typedef value_functor_type value_function_type;
+    typedef std::size_t ref_counter_type;
+    struct map_value_type;
+    typedef std::map<key_type, map_value_type> map_storage_type;
+    typedef std::list<typename map_storage_type::iterator> lru_list_type;
+    struct map_value_type {
+        value_type my_value;
+        ref_counter_type my_ref_counter;
+        typename lru_list_type::iterator my_lru_list_iterator;
+        bool my_is_ready;
+
+        map_value_type (value_type const& a_value,  ref_counter_type a_ref_counter,    typename lru_list_type::iterator a_lru_list_iterator, bool a_is_ready)
+            : my_value(a_value), my_ref_counter(a_ref_counter), my_lru_list_iterator (a_lru_list_iterator), my_is_ready(a_is_ready)
+        {}
+    };
+
+    class handle_object;
+
+    struct aggregator_operation;
+    typedef aggregator_operation aggregated_operation_type;
+    typedef tbb::internal::aggregating_functor<self_type,aggregated_operation_type> aggregator_function_type;
+    friend class tbb::internal::aggregating_functor<self_type,aggregated_operation_type>;
+    typedef tbb::internal::aggregator<aggregator_function_type, aggregated_operation_type> aggregator_type;
+
+private:
+    value_function_type my_value_function;
+    std::size_t const my_number_of_lru_history_items;
+    map_storage_type my_map_storage;
+    lru_list_type my_lru_list;
+    aggregator_type my_aggregator;
+
+public:
+    typedef handle_object handle;
+
+public:
+    concurrent_lru_cache(value_function_type f, std::size_t number_of_lru_history_items)
+        : my_value_function(f),my_number_of_lru_history_items(number_of_lru_history_items)
+    {
+        my_aggregator.initialize_handler(aggregator_function_type(this));
+    }
+
+    handle_object operator[](key_type k){
+        retrieve_aggregator_operation op(k);
+        my_aggregator.execute(&op);
+        if (op.is_new_value_needed()){
+             op.result().second.my_value = my_value_function(k);
+             __TBB_store_with_release(op.result().second.my_is_ready, true);
+        }else{
+            tbb::internal::spin_wait_while_eq(op.result().second.my_is_ready,false);
+        }
+        return handle_object(*this,op.result());
+    }
+private:
+    void signal_end_of_usage(typename map_storage_type::reference value_ref){
+        signal_end_of_usage_aggregator_operation op(value_ref);
+        my_aggregator.execute(&op);
+    }
+
+private:
+    struct handle_move_t:no_assign{
+        concurrent_lru_cache & my_cache_ref;
+        typename map_storage_type::reference my_map_record_ref;
+        handle_move_t(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_ref(cache_ref),my_map_record_ref(value_ref) {};
+    };
+    class handle_object {
+        concurrent_lru_cache * my_cache_pointer;
+        typename map_storage_type::reference my_map_record_ref;
+    public:
+        handle_object(concurrent_lru_cache & cache_ref, typename map_storage_type::reference value_ref):my_cache_pointer(&cache_ref), my_map_record_ref(value_ref) {}
+        handle_object(handle_move_t m):my_cache_pointer(&m.my_cache_ref), my_map_record_ref(m.my_map_record_ref){}
+        operator handle_move_t(){ return move(*this);}
+        value_type& value(){
+            __TBB_ASSERT(my_cache_pointer,"get value from moved from object?");
+            return my_map_record_ref.second.my_value;
+        }
+        ~handle_object(){
+            if (my_cache_pointer){
+                my_cache_pointer->signal_end_of_usage(my_map_record_ref);
+            }
+        }
+    private:
+        friend handle_move_t move(handle_object& h){
+            return handle_object::move(h);
+        }
+        static handle_move_t move(handle_object& h){
+            __TBB_ASSERT(h.my_cache_pointer,"move from the same object twice ?");
+            concurrent_lru_cache * cache_pointer = NULL;
+            std::swap(cache_pointer,h.my_cache_pointer);
+            return handle_move_t(*cache_pointer,h.my_map_record_ref);
+        }
+    private:
+        void operator=(handle_object&);
+#if __SUNPRO_CC
+    // Presumably due to a compiler error, private copy constructor
+    // breaks expressions like handle h = cache[key];
+    public:
+#endif
+        handle_object(handle_object &);
+    };
+private:
+    //TODO: looks like aggregator_operation is a perfect match for statically typed variant type
+    struct aggregator_operation : tbb::internal::aggregated_operation<aggregator_operation>{
+        enum e_op_type {op_retive, op_signal_end_of_usage};
+        //TODO: try to use pointer to function apply_visitor here
+        //TODO: try virtual functions and measure the difference
+        e_op_type my_operation_type;
+        aggregator_operation(e_op_type operation_type): my_operation_type(operation_type) {}
+        void cast_and_handle(self_type& container ){
+            if (my_operation_type==op_retive){
+                static_cast<retrieve_aggregator_operation*>(this)->handle(container);
+            }else{
+                static_cast<signal_end_of_usage_aggregator_operation*>(this)->handle(container);
+            }
+        }
+    };
+    struct retrieve_aggregator_operation : aggregator_operation, private internal::no_assign {
+        key_type my_key;
+        typename map_storage_type::pointer my_result_map_record_pointer;
+        bool my_is_new_value_needed;
+        retrieve_aggregator_operation(key_type key):aggregator_operation(aggregator_operation::op_retive),my_key(key),my_is_new_value_needed(false){}
+        void handle(self_type& container ){
+            my_result_map_record_pointer = & container.retrieve_serial(my_key,my_is_new_value_needed);
+        }
+        typename map_storage_type::reference result(){ return * my_result_map_record_pointer; }
+        bool is_new_value_needed(){return my_is_new_value_needed;}
+    };
+    struct signal_end_of_usage_aggregator_operation : aggregator_operation, private internal::no_assign {
+        typename map_storage_type::reference my_map_record_ref;
+        signal_end_of_usage_aggregator_operation(typename map_storage_type::reference map_record_ref):aggregator_operation(aggregator_operation::op_signal_end_of_usage),my_map_record_ref(map_record_ref){}
+        void handle(self_type& container ){
+            container.signal_end_of_usage_serial(my_map_record_ref);
+        }
+    };
+
+private:
+   void handle_operations(aggregator_operation* op_list){
+       while(op_list){
+           op_list->cast_and_handle(*this);
+           aggregator_operation* tmp = op_list;
+           op_list=op_list->next;
+           tbb::internal::itt_store_word_with_release(tmp->status, uintptr_t(1));
+       }
+   }
+
+private:
+   typename map_storage_type::reference retrieve_serial(key_type k, bool& is_new_value_needed){
+        typename map_storage_type::iterator it = my_map_storage.find(k);
+        if (it == my_map_storage.end()){
+            it = my_map_storage.insert(it,std::make_pair(k,map_value_type(value_type(),0,my_lru_list.end(),false)));
+            is_new_value_needed = true;
+        }else {
+            typename lru_list_type::iterator list_it = it->second.my_lru_list_iterator;
+            if (list_it!=my_lru_list.end()) {
+                __TBB_ASSERT(!it->second.my_ref_counter,"item to be evicted should not have a live references");
+                //item is going to be used. Therefore it is not a subject for eviction
+                //so - remove it from LRU history.
+                my_lru_list.erase(list_it);
+                it->second.my_lru_list_iterator= my_lru_list.end();
+            }
+        }
+        ++(it->second.my_ref_counter);
+        return *it;
+    }
+
+    void signal_end_of_usage_serial(typename map_storage_type::reference map_record_ref){
+        typename map_storage_type::iterator it = my_map_storage.find(map_record_ref.first);
+        __TBB_ASSERT(it!=my_map_storage.end(),"cache should not return past-end iterators to outer world");
+        __TBB_ASSERT(&(*it) == &map_record_ref,"dangling reference has been returned to outside world? data race ?");
+        __TBB_ASSERT( my_lru_list.end()== std::find(my_lru_list.begin(),my_lru_list.end(),it),
+                "object in use should not be in list of unused objects ");
+        if (! --(it->second.my_ref_counter)){
+            //it was the last reference so put it to the LRU history
+            if (my_lru_list.size()>=my_number_of_lru_history_items){
+                //evict items in order to get a space
+                size_t number_of_elements_to_evict = 1 + my_lru_list.size() - my_number_of_lru_history_items;
+                for (size_t i=0; i<number_of_elements_to_evict; ++i){
+                    typename map_storage_type::iterator it_to_evict = my_lru_list.back();
+                    __TBB_ASSERT(!it_to_evict->second.my_ref_counter,"item to be evicted should not have a live references");
+                    my_lru_list.pop_back();
+                    my_map_storage.erase(it_to_evict);
+                }
+            }
+            my_lru_list.push_front(it);
+            it->second.my_lru_list_iterator = my_lru_list.begin();
+        }
+    }
+};
+} // namespace interface6
+
+using interface6::concurrent_lru_cache;
+
+} // namespace tbb
+#endif //__TBB_concurrent_lru_cache_H
index b5601f15a2dbbe5affbfa8ef94c91c85b4b2990a..247c91819e64b2572b8173d15fd19afb64af8dcf 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_concurrent_priority_queue_H
 #include <iterator>
 #include <functional>
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    #include <initializer_list>
+#endif
+
+#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT
+    #include <type_traits>
+#endif
+
 namespace tbb {
 namespace interface5 {
+namespace internal {
+#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT
+    template<typename T, bool C = std::is_copy_constructible<T>::value>
+    struct use_element_copy_constructor {
+        typedef tbb::internal::true_type type;
+    };
+    template<typename T>
+    struct use_element_copy_constructor <T,false> {
+        typedef tbb::internal::false_type type;
+    };
+#else
+    template<typename>
+    struct use_element_copy_constructor {
+        typedef tbb::internal::true_type type;
+    };
+#endif
+} // namespace internal
 
 using namespace tbb::internal;
 
@@ -83,13 +100,23 @@ class concurrent_priority_queue {
     //! [begin,end) constructor
     template<typename InputIterator>
     concurrent_priority_queue(InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) :
-        data(begin, end, a)
+        mark(0), data(begin, end, a)
+    {
+        my_aggregator.initialize_handler(my_functor_t(this));
+        heapify();
+        my_size = data.size();
+    }
+
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Constructor from std::initializer_list
+    concurrent_priority_queue(std::initializer_list<T> init_list, const allocator_type &a = allocator_type()) :
+        mark(0),data(init_list.begin(), init_list.end(), a)
     {
-        mark = 0;
         my_aggregator.initialize_handler(my_functor_t(this));
         heapify();
         my_size = data.size();
     }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
 
     //! Copy constructor
     /** This operation is unsafe if there are pending concurrent operations on the src queue. */
@@ -113,12 +140,83 @@ class concurrent_priority_queue {
     /** This operation is unsafe if there are pending concurrent operations on the src queue. */
     concurrent_priority_queue& operator=(const concurrent_priority_queue& src) {
         if (this != &src) {
-            std::vector<value_type, allocator_type>(src.data.begin(), src.data.end(), src.data.get_allocator()).swap(data);
+            vector_t(src.data.begin(), src.data.end(), src.data.get_allocator()).swap(data);
+            mark = src.mark;
+            my_size = src.my_size;
+        }
+        return *this;
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move constructor
+    /** This operation is unsafe if there are pending concurrent operations on the src queue. */
+    concurrent_priority_queue(concurrent_priority_queue&& src) : mark(src.mark),
+        my_size(src.my_size), data(std::move(src.data))
+    {
+        my_aggregator.initialize_handler(my_functor_t(this));
+    }
+
+    //! Move constructor with specific allocator
+    /** This operation is unsafe if there are pending concurrent operations on the src queue. */
+    concurrent_priority_queue(concurrent_priority_queue&& src, const allocator_type& a) : mark(src.mark),
+        my_size(src.my_size),
+#if __TBB_ALLOCATOR_TRAITS_PRESENT
+        data(std::move(src.data), a)
+#else
+    // Some early version of C++11 STL vector does not have a constructor of vector(vector&& , allocator).
+    // It seems that the reason is absence of support of allocator_traits (stateful allocators).
+        data(a)
+#endif //__TBB_ALLOCATOR_TRAITS_PRESENT
+    {
+        my_aggregator.initialize_handler(my_functor_t(this));
+#if !__TBB_ALLOCATOR_TRAITS_PRESENT
+        if (a != src.data.get_allocator()){
+            data.reserve(src.data.size());
+            data.assign(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end()));
+        }else{
+            data = std::move(src.data);
+        }
+#endif //!__TBB_ALLOCATOR_TRAITS_PRESENT
+    }
+
+    //! Move assignment operator
+    /** This operation is unsafe if there are pending concurrent operations on the src queue. */
+    concurrent_priority_queue& operator=( concurrent_priority_queue&& src) {
+        if (this != &src) {
             mark = src.mark;
             my_size = src.my_size;
+#if !__TBB_ALLOCATOR_TRAITS_PRESENT
+            if (data.get_allocator() != src.data.get_allocator()){
+                vector_t(std::make_move_iterator(src.data.begin()), std::make_move_iterator(src.data.end()), data.get_allocator()).swap(data);
+            }else
+#endif //!__TBB_ALLOCATOR_TRAITS_PRESENT
+            {
+                data = std::move(src.data);
+            }
         }
         return *this;
     }
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
+    //! Assign the queue from [begin,end) range, not thread-safe
+    template<typename InputIterator>
+    void assign(InputIterator begin, InputIterator end) {
+        vector_t(begin, end, data.get_allocator()).swap(data);
+        mark = 0;
+        my_size = data.size();
+        heapify();
+    }
+
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Assign the queue from std::initializer_list, not thread-safe
+    void assign(std::initializer_list<T> il) { this->assign(il.begin(), il.end()); }
+
+    //! Assign from std::initializer_list, not thread-safe
+    concurrent_priority_queue& operator=(std::initializer_list<T> il) {
+        this->assign(il.begin(), il.end());
+        return *this;
+    }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
 
     //! Returns true if empty, false otherwise
     /** Returned value may not reflect results of pending operations.
@@ -131,18 +229,41 @@ class concurrent_priority_queue {
     size_type size() const { return __TBB_load_with_acquire(my_size); }
 
     //! Pushes elem onto the queue, increasing capacity of queue if necessary
-    /** This operation can be safely used concurrently with other push, try_pop or reserve operations. */
+    /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */
     void push(const_reference elem) {
+#if __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT
+        __TBB_STATIC_ASSERT( std::is_copy_constructible<value_type>::value, "The type is not copy constructible. Copying push operation is impossible." );
+#endif
         cpq_operation op_data(elem, PUSH_OP);
         my_aggregator.execute(&op_data);
         if (op_data.status == FAILED) // exception thrown
             throw_exception(eid_bad_alloc);
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Pushes elem onto the queue, increasing capacity of queue if necessary
+    /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */
+    void push(value_type &&elem) {
+        cpq_operation op_data(elem, PUSH_RVALUE_OP);
+        my_aggregator.execute(&op_data);
+        if (op_data.status == FAILED) // exception thrown
+            throw_exception(eid_bad_alloc);
+    }
+
+#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+    //! Constructs a new element using args as the arguments for its construction and pushes it onto the queue */
+    /** This operation can be safely used concurrently with other push, try_pop or emplace operations. */
+    template<typename... Args>
+    void emplace(Args&&... args) {
+        push(value_type(std::forward<Args>(args)...));
+    }
+#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
     //! Gets a reference to and removes highest priority element
     /** If a highest priority element was found, sets elem and returns true,
         otherwise returns false.
-        This operation can be safely used concurrently with other push, try_pop or reserve operations. */
+        This operation can be safely used concurrently with other push, try_pop or emplace operations. */
     bool try_pop(reference elem) {
         cpq_operation op_data(POP_OP);
         op_data.elem = &elem;
@@ -163,16 +284,17 @@ class concurrent_priority_queue {
     //! Swap this queue with another; not thread-safe
     /** This operation is unsafe if there are pending concurrent operations on the queue. */
     void swap(concurrent_priority_queue& q) {
+        using std::swap;
         data.swap(q.data);
-        std::swap(mark, q.mark);
-        std::swap(my_size, q.my_size);
+        swap(mark, q.mark);
+        swap(my_size, q.my_size);
     }
 
     //! Return allocator object
     allocator_type get_allocator() const { return data.get_allocator(); }
 
  private:
-    enum operation_type {INVALID_OP, PUSH_OP, POP_OP};
+    enum operation_type {INVALID_OP, PUSH_OP, POP_OP, PUSH_RVALUE_OP};
     enum operation_status { WAIT=0, SUCCEEDED, FAILED };
 
     class cpq_operation : public aggregated_operation<cpq_operation> {
@@ -197,9 +319,10 @@ class concurrent_priority_queue {
         }
     };
 
-    aggregator< my_functor_t, cpq_operation> my_aggregator;
+    typedef tbb::internal::aggregator< my_functor_t, cpq_operation > aggregator_t;
+    aggregator_t my_aggregator;
     //! Padding added to avoid false sharing
-    char padding1[NFS_MaxLineSize - sizeof(aggregator< my_functor_t, cpq_operation >)];
+    char padding1[NFS_MaxLineSize - sizeof(aggregator_t)];
     //! The point at which unsorted elements begin
     size_type mark;
     __TBB_atomic size_type my_size;
@@ -224,15 +347,15 @@ class concurrent_priority_queue {
         mark-1 (it may be empty).  Then there are 0 or more elements
         that have not yet been inserted into the heap, in positions
         mark through my_size-1. */
-    std::vector<value_type, allocator_type> data;
+    typedef std::vector<value_type, allocator_type> vector_t;
+    vector_t data;
 
     void handle_operations(cpq_operation *op_list) {
         cpq_operation *tmp, *pop_list=NULL;
 
         __TBB_ASSERT(mark == data.size(), NULL);
 
-        // first pass processes all constant time operations: pushes,
-        // tops, some pops. Also reserve.
+        // First pass processes all constant (amortized; reallocation may happen) time pushes and pops.
         while (op_list) {
             // ITT note: &(op_list->status) tag is used to cover accesses to op_list
             // node. This thread is going to handle the operation, and so will acquire it
@@ -245,22 +368,12 @@ class concurrent_priority_queue {
             __TBB_ASSERT(op_list->type != INVALID_OP, NULL);
             tmp = op_list;
             op_list = itt_hide_load_word(op_list->next);
-            if (tmp->type == PUSH_OP) {
-                __TBB_TRY {
-                    data.push_back(*(tmp->elem));
-                    __TBB_store_with_release(my_size, my_size+1);
-                    itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
-                } __TBB_CATCH(...) {
-                    itt_store_word_with_release(tmp->status, uintptr_t(FAILED));
-                }
-            }
-            else { // tmp->type == POP_OP
-                __TBB_ASSERT(tmp->type == POP_OP, NULL);
+            if (tmp->type == POP_OP) {
                 if (mark < data.size() &&
                     compare(data[0], data[data.size()-1])) {
                     // there are newly pushed elems and the last one
                     // is higher than top
-                    *(tmp->elem) = data[data.size()-1]; // copy the data
+                    *(tmp->elem) = move(data[data.size()-1]);
                     __TBB_store_with_release(my_size, my_size-1);
                     itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
                     data.pop_back();
@@ -270,6 +383,19 @@ class concurrent_priority_queue {
                     itt_hide_store_word(tmp->next, pop_list);
                     pop_list = tmp;
                 }
+            } else { // PUSH_OP or PUSH_RVALUE_OP
+                __TBB_ASSERT(tmp->type == PUSH_OP || tmp->type == PUSH_RVALUE_OP, "Unknown operation" );
+                __TBB_TRY{
+                    if (tmp->type == PUSH_OP) {
+                        push_back_helper(*(tmp->elem), typename internal::use_element_copy_constructor<value_type>::type());
+                    } else {
+                        data.push_back(move(*(tmp->elem)));
+                    }
+                    __TBB_store_with_release(my_size, my_size + 1);
+                    itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
+                } __TBB_CATCH(...) {
+                    itt_store_word_with_release(tmp->status, uintptr_t(FAILED));
+                }
             }
         }
 
@@ -287,13 +413,13 @@ class concurrent_priority_queue {
                     compare(data[0], data[data.size()-1])) {
                     // there are newly pushed elems and the last one is
                     // higher than top
-                    *(tmp->elem) = data[data.size()-1]; // copy the data
+                    *(tmp->elem) = move(data[data.size()-1]);
                     __TBB_store_with_release(my_size, my_size-1);
                     itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
                     data.pop_back();
                 }
                 else { // extract top and push last element down heap
-                    *(tmp->elem) = data[0]; // copy the data
+                    *(tmp->elem) = move(data[0]);
                     __TBB_store_with_release(my_size, my_size-1);
                     itt_store_word_with_release(tmp->status, uintptr_t(SUCCEEDED));
                     reheap();
@@ -313,14 +439,14 @@ class concurrent_priority_queue {
         for (; mark<data.size(); ++mark) {
             // for each unheapified element under size
             size_type cur_pos = mark;
-            value_type to_place = data[mark];
+            value_type to_place = move(data[mark]);
             do { // push to_place up the heap
                 size_type parent = (cur_pos-1)>>1;
                 if (!compare(data[parent], to_place)) break;
-                data[cur_pos] = data[parent];
+                data[cur_pos] = move(data[parent]);
                 cur_pos = parent;
             } while( cur_pos );
-            data[cur_pos] = to_place;
+            data[cur_pos] = move(to_place);
         }
     }
 
@@ -335,14 +461,23 @@ class concurrent_priority_queue {
                 ++target;
             // target now has the higher priority child
             if (compare(data[target], data[data.size()-1])) break;
-            data[cur_pos] = data[target];
+            data[cur_pos] = move(data[target]);
             cur_pos = target;
             child = (cur_pos<<1)+1;
         }
-        data[cur_pos] = data[data.size()-1];
+        if (cur_pos != data.size()-1)
+            data[cur_pos] = move(data[data.size()-1]);
         data.pop_back();
         if (mark > data.size()) mark = data.size();
     }
+
+    void push_back_helper(const T& t, tbb::internal::true_type) {
+        data.push_back(t);
+    }
+
+    void push_back_helper(const T&, tbb::internal::false_type) {
+        __TBB_ASSERT( false, "The type is not copy constructible. Copying push operation is impossible." );
+    }
 };
 
 } // namespace interface5
index cc7ac33599a02539712dca592924003a3c0d9f0b..2cead237c5da26094c3ee37d01e642c578eed74f 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_concurrent_queue_H
@@ -60,6 +52,15 @@ class concurrent_queue: public internal::concurrent_queue_base_v3<T> {
         my_allocator.deallocate( reinterpret_cast<char*>(b), n );
     }
 
+    static void copy_construct_item(T* location, const void* src){
+        new (location) T(*static_cast<const T*>(src));
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    static void move_construct_item(T* location, const void* src) {
+        new (location) T( std::move(*static_cast<T*>(const_cast<void*>(src))) );
+    }
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
 public:
     //! Element type in the queue.
     typedef T value_type;
@@ -80,7 +81,7 @@ public:
     typedef A allocator_type;
 
     //! Construct empty queue
-    explicit concurrent_queue(const allocator_type& a = allocator_type()) : 
+    explicit concurrent_queue(const allocator_type& a = allocator_type()) :
         my_allocator( a )
     {
     }
@@ -91,24 +92,60 @@ public:
         my_allocator( a )
     {
         for( ; begin != end; ++begin )
-            this->internal_push(&*begin);
+            this->push(*begin);
     }
-    
+
     //! Copy constructor
-    concurrent_queue( const concurrent_queue& src, const allocator_type& a = allocator_type()) : 
+    concurrent_queue( const concurrent_queue& src, const allocator_type& a = allocator_type()) :
+        internal::concurrent_queue_base_v3<T>(), my_allocator( a )
+    {
+        this->assign( src, copy_construct_item );
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move constructors
+    concurrent_queue( concurrent_queue&& src ) :
+        internal::concurrent_queue_base_v3<T>(), my_allocator( std::move(src.my_allocator) )
+    {
+        this->internal_swap( src );
+    }
+
+    concurrent_queue( concurrent_queue&& src, const allocator_type& a ) :
         internal::concurrent_queue_base_v3<T>(), my_allocator( a )
     {
-        this->assign( src );
+        // checking that memory allocated by one instance of allocator can be deallocated
+        // with another
+        if( my_allocator == src.my_allocator) {
+            this->internal_swap( src );
+        } else {
+            // allocators are different => performing per-element move
+            this->assign( src, move_construct_item );
+            src.clear();
+        }
     }
-    
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
     //! Destroy queue
     ~concurrent_queue();
 
     //! Enqueue an item at tail of queue.
     void push( const T& source ) {
-        this->internal_push( &source );
+        this->internal_push( &source, copy_construct_item );
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    void push( T&& source ) {
+        this->internal_push( &source, move_construct_item );
     }
 
+#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+    template<typename... Arguments>
+    void emplace( Arguments&&... args ) {
+        push( T(std::forward<Arguments>( args )...) );
+    }
+#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
     //! Attempt to dequeue an item from head of queue.
     /** Does not wait for item to become available.
         Returns true if successful; false otherwise. */
@@ -155,7 +192,7 @@ void concurrent_queue<T,A>::clear() {
 }
 
 } // namespace strict_ppl
-    
+
 //! A high-performance thread-safe blocking concurrent bounded queue.
 /** This is the pre-PPL TBB concurrent queue which supports boundedness and blocking semantics.
     Note that method names agree with the PPL-style concurrent queue.
@@ -163,7 +200,7 @@ void concurrent_queue<T,A>::clear() {
     Assignment construction is not allowed.
     @ingroup containers */
 template<typename T, class A = cache_aligned_allocator<T> >
-class concurrent_bounded_queue: public internal::concurrent_queue_base_v3 {
+class concurrent_bounded_queue: public internal::concurrent_queue_base_v8 {
     template<typename Container, typename Value> friend class internal::concurrent_queue_iterator;
 
     //! Allocator type
@@ -171,13 +208,14 @@ class concurrent_bounded_queue: public internal::concurrent_queue_base_v3 {
     page_allocator_type my_allocator;
 
     typedef typename concurrent_queue_base_v3::padded_page<T> padded_page;
-    //! Class used to ensure exception-safety of method "pop" 
+    typedef typename concurrent_queue_base_v3::copy_specifics copy_specifics;
+
+    //! Class used to ensure exception-safety of method "pop"
     class destroyer: internal::no_copy {
         T& my_value;
     public:
         destroyer( T& value ) : my_value(value) {}
-        ~destroyer() {my_value.~T();}          
+        ~destroyer() {my_value.~T();}
     };
 
     T& get_ref( page& p, size_t index ) {
@@ -186,24 +224,44 @@ class concurrent_bounded_queue: public internal::concurrent_queue_base_v3 {
     }
 
     /*override*/ virtual void copy_item( page& dst, size_t index, const void* src ) {
-        new( &get_ref(dst,index) ) T(*static_cast<const T*>(src)); 
+        new( &get_ref(dst,index) ) T(*static_cast<const T*>(src));
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    /*override*/ virtual void move_item( page& dst, size_t index, const void* src ) {
+        new( &get_ref(dst,index) ) T( std::move(*static_cast<T*>(const_cast<void*>(src))) );
+    }
+#else
+    /*override*/ virtual void move_item( page&, size_t, const void* ) {
+        __TBB_ASSERT( false, "Unreachable code" );
     }
+#endif
 
     /*override*/ virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) {
         new( &get_ref(dst,dindex) ) T( get_ref( const_cast<page&>(src), sindex ) );
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    /*override*/ virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) {
+        new( &get_ref(dst,dindex) ) T( std::move(get_ref( const_cast<page&>(src), sindex )) );
+    }
+#else
+    /*override*/ virtual void move_page_item( page&, size_t, const page&, size_t ) {
+        __TBB_ASSERT( false, "Unreachable code" );
+    }
+#endif
+
     /*override*/ virtual void assign_and_destroy_item( void* dst, page& src, size_t index ) {
         T& from = get_ref(src,index);
         destroyer d(from);
-        *static_cast<T*>(dst) = from;
+        *static_cast<T*>(dst) = tbb::internal::move( from );
     }
 
     /*override*/ virtual page *allocate_page() {
         size_t n = sizeof(padded_page) + (items_per_page-1)*sizeof(T);
         page *p = reinterpret_cast<page*>(my_allocator.allocate( n ));
         if( !p )
-            internal::throw_exception(internal::eid_bad_alloc); 
+            internal::throw_exception(internal::eid_bad_alloc);
         return p;
     }
 
@@ -235,21 +293,45 @@ public:
 
     //! Construct empty queue
     explicit concurrent_bounded_queue(const allocator_type& a = allocator_type()) : 
-        concurrent_queue_base_v3( sizeof(T) ), my_allocator( a )
+        concurrent_queue_base_v8( sizeof(T) ), my_allocator( a )
     {
     }
 
     //! Copy constructor
-    concurrent_bounded_queue( const concurrent_bounded_queue& src, const allocator_type& a = allocator_type()) : 
-        concurrent_queue_base_v3( sizeof(T) ), my_allocator( a )
+    concurrent_bounded_queue( const concurrent_bounded_queue& src, const allocator_type& a = allocator_type())
+        : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a )
     {
         assign( src );
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move constructors
+    concurrent_bounded_queue( concurrent_bounded_queue&& src )
+        : concurrent_queue_base_v8( sizeof(T) ), my_allocator( std::move(src.my_allocator) )
+    {
+        internal_swap( src );
+    }
+
+    concurrent_bounded_queue( concurrent_bounded_queue&& src, const allocator_type& a )
+        : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a )
+    {
+        // checking that memory allocated by one instance of allocator can be deallocated
+        // with another
+        if( my_allocator == src.my_allocator) {
+            this->internal_swap( src );
+        } else {
+            // allocators are different => performing per-element move
+            this->move_content( src );
+            src.clear();
+        }
+    }
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
     //! [begin,end) constructor
     template<typename InputIterator>
-    concurrent_bounded_queue( InputIterator begin, InputIterator end, const allocator_type& a = allocator_type()) :
-        concurrent_queue_base_v3( sizeof(T) ), my_allocator( a )
+    concurrent_bounded_queue( InputIterator begin, InputIterator end,
+                              const allocator_type& a = allocator_type())
+        : concurrent_queue_base_v8( sizeof(T) ), my_allocator( a )
     {
         for( ; begin != end; ++begin )
             internal_push_if_not_full(&*begin);
@@ -263,12 +345,33 @@ public:
         internal_push( &source );
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move an item at tail of queue.
+    void push( T&& source ) {
+        internal_push_move( &source );
+    }
+
+#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+    template<typename... Arguments>
+    void emplace( Arguments&&... args ) {
+        push( T(std::forward<Arguments>( args )...) );
+    }
+#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
     //! Dequeue item from head of queue.
     /** Block until an item becomes available, and then dequeue it. */
     void pop( T& destination ) {
         internal_pop( &destination );
     }
 
+#if TBB_USE_EXCEPTIONS
+    //! Abort all pending queue operations
+    void abort() {
+        internal_abort();
+    }
+#endif
+
     //! Enqueue an item at tail of queue if queue is not already full.
     /** Does not wait for queue to become not full.
         Returns true if item is pushed; false if queue was already full. */
@@ -276,6 +379,21 @@ public:
         return internal_push_if_not_full( &source );
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move an item at tail of queue if queue is not already full.
+    /** Does not wait for queue to become not full.
+        Returns true if item is pushed; false if queue was already full. */
+    bool try_push( T&& source ) {
+        return internal_push_move_if_not_full( &source );
+    }
+#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+    template<typename... Arguments>
+    bool try_emplace( Arguments&&... args ) {
+        return try_push( T(std::forward<Arguments>( args )...) );
+    }
+#endif /* __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT */
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
     //! Attempt to dequeue an item from head of queue.
     /** Does not wait for item to become available.
         Returns true if successful; false otherwise. */
@@ -337,76 +455,7 @@ void concurrent_bounded_queue<T,A>::clear() {
     }
 }
 
-namespace deprecated {
-
-//! A high-performance thread-safe blocking concurrent bounded queue.
-/** This is the pre-PPL TBB concurrent queue which support boundedness and blocking semantics.
-    Note that method names agree with the PPL-style concurrent queue.
-    Multiple threads may each push and pop concurrently.
-    Assignment construction is not allowed.
-    @ingroup containers */
-template<typename T, class A = cache_aligned_allocator<T> > 
-class concurrent_queue: public concurrent_bounded_queue<T,A> {
-#if !__TBB_TEMPLATE_FRIENDS_BROKEN
-    template<typename Container, typename Value> friend class internal::concurrent_queue_iterator;
-#endif 
-
-public:
-    //! Construct empty queue
-    explicit concurrent_queue(const A& a = A()) : 
-        concurrent_bounded_queue<T,A>( a )
-    {
-    }
-
-    //! Copy constructor
-    concurrent_queue( const concurrent_queue& src, const A& a = A()) : 
-        concurrent_bounded_queue<T,A>( src, a )
-    {
-    }
-
-    //! [begin,end) constructor
-    template<typename InputIterator>
-    concurrent_queue( InputIterator b /*begin*/, InputIterator e /*end*/, const A& a = A()) :
-        concurrent_bounded_queue<T,A>( b, e, a )
-    {
-    }
-
-    //! Enqueue an item at tail of queue if queue is not already full.
-    /** Does not wait for queue to become not full.
-        Returns true if item is pushed; false if queue was already full. */
-    bool push_if_not_full( const T& source ) {
-        return this->try_push( source );
-    }
-
-    //! Attempt to dequeue an item from head of queue.
-    /** Does not wait for item to become available.
-        Returns true if successful; false otherwise. 
-        @deprecated Use try_pop()
-        */
-    bool pop_if_present( T& destination ) {
-        return this->try_pop( destination );
-    }
-
-    typedef typename concurrent_bounded_queue<T,A>::iterator iterator;
-    typedef typename concurrent_bounded_queue<T,A>::const_iterator const_iterator;
-    //
-    //------------------------------------------------------------------------
-    // The iterators are intended only for debugging.  They are slow and not thread safe.
-    //------------------------------------------------------------------------
-    iterator begin() {return this->unsafe_begin();}
-    iterator end() {return this->unsafe_end();}
-    const_iterator begin() const {return this->unsafe_begin();}
-    const_iterator end() const {return this->unsafe_end();}
-}; 
-
-}
-    
-
-#if TBB_DEPRECATED
-using deprecated::concurrent_queue;
-#else
-using strict_ppl::concurrent_queue;    
-#endif
+using strict_ppl::concurrent_queue;
 
 } // namespace tbb
 
index e14fad0b5b371f486b578606c2c799f8f36fe082..b2f54174a2b9b82f17d7120da552a18e388104f7 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 /* Container implementations in this header are based on PPL implementations
@@ -77,14 +69,16 @@ protected:
     hash_compare my_hash_compare; // the comparator predicate for keys
 };
 
-template <typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>, typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
-class concurrent_unordered_map : public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
+template <typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
+         typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
+class concurrent_unordered_map :
+    public internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T,
+    internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> >
 {
     // Base type definitions
     typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
-    typedef internal::concurrent_unordered_base< concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, false> > base_type;
-    typedef concurrent_unordered_map_traits<Key, T, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> traits_type;
-    using traits_type::my_hash_compare;
+    typedef concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, false> traits_type;
+    typedef internal::concurrent_unordered_base< traits_type > base_type;
 #if __TBB_EXTRA_DEBUG
 public:
 #endif
@@ -117,71 +111,70 @@ public:
     typedef typename base_type::const_iterator const_local_iterator;
 
     // Construction/destruction/copying
-    explicit concurrent_unordered_map(size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
-        const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
-        : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
+    explicit concurrent_unordered_map(size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
     {
     }
 
-    concurrent_unordered_map(const Allocator& a) : base_type(8, key_compare(), a)
+    concurrent_unordered_map(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
     {
     }
 
     template <typename Iterator>
-    concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
-        const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
-        : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
+    concurrent_unordered_map(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
     {
-        for (; first != last; ++first)
-            base_type::insert(*first);
+        insert(first, last);
     }
 
-    concurrent_unordered_map(const concurrent_unordered_map& table) : base_type(table)
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Constructor from initializer_list
+    concurrent_unordered_map(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
     {
+        this->insert(il.begin(),il.end());
     }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
 
-    concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
-        : base_type(table, a)
+#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+    concurrent_unordered_map(const concurrent_unordered_map& table)
+        : base_type(table)
     {
     }
 
     concurrent_unordered_map& operator=(const concurrent_unordered_map& table)
     {
-        base_type::operator=(table);
-        return (*this);
+        return static_cast<concurrent_unordered_map&>(base_type::operator=(table));
     }
 
-    iterator unsafe_erase(const_iterator where)
+    concurrent_unordered_map(concurrent_unordered_map&& table)
+        : base_type(std::move(table))
     {
-        return base_type::unsafe_erase(where);
     }
 
-    size_type unsafe_erase(const key_type& key)
+    concurrent_unordered_map& operator=(concurrent_unordered_map&& table)
     {
-        return base_type::unsafe_erase(key);
+        return static_cast<concurrent_unordered_map&>(base_type::operator=(std::move(table)));
     }
+#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
 
-    iterator unsafe_erase(const_iterator first, const_iterator last)
+    concurrent_unordered_map(const concurrent_unordered_map& table, const Allocator& a)
+        : base_type(table, a)
     {
-        return base_type::unsafe_erase(first, last);
     }
 
-    void swap(concurrent_unordered_map& table)
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    concurrent_unordered_map(concurrent_unordered_map&& table, const Allocator& a) : base_type(std::move(table), a)
     {
-        base_type::swap(table);
     }
-
+#endif
     // Observers
-    hasher hash_function() const
-    {
-        return my_hash_compare.my_hash_object;
-    }
-
-    key_equal key_eq() const
-    {
-        return my_hash_compare.my_key_compare_object;
-    }
-
     mapped_type& operator[](const key_type& key)
     {
         iterator where = find(key);
@@ -219,9 +212,114 @@ public:
     }
 };
 
+template < typename Key, typename T, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
+        typename Allocator = tbb::tbb_allocator<std::pair<const Key, T> > >
+class concurrent_unordered_multimap :
+    public internal::concurrent_unordered_base< concurrent_unordered_map_traits< Key, T,
+    internal::hash_compare<Key, Hasher, Key_equality>, Allocator, true> >
+{
+    // Base type definitions
+    typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
+    typedef concurrent_unordered_map_traits<Key, T, hash_compare, Allocator, true> traits_type;
+    typedef internal::concurrent_unordered_base<traits_type> base_type;
+#if __TBB_EXTRA_DEBUG
+public:
+#endif
+    using traits_type::allow_multimapping;
+public:
+    using base_type::insert;
+
+    // Type definitions
+    typedef Key key_type;
+    typedef typename base_type::value_type value_type;
+    typedef T mapped_type;
+    typedef Hasher hasher;
+    typedef Key_equality key_equal;
+    typedef hash_compare key_compare;
+
+    typedef typename base_type::allocator_type allocator_type;
+    typedef typename base_type::pointer pointer;
+    typedef typename base_type::const_pointer const_pointer;
+    typedef typename base_type::reference reference;
+    typedef typename base_type::const_reference const_reference;
+
+    typedef typename base_type::size_type size_type;
+    typedef typename base_type::difference_type difference_type;
+
+    typedef typename base_type::iterator iterator;
+    typedef typename base_type::const_iterator const_iterator;
+    typedef typename base_type::iterator local_iterator;
+    typedef typename base_type::const_iterator const_local_iterator;
+
+    // Construction/destruction/copying
+    explicit concurrent_unordered_multimap(size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
+    {
+    }
+
+    concurrent_unordered_multimap(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
+    {
+    }
+
+    template <typename Iterator>
+    concurrent_unordered_multimap(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets,key_compare(_Hasher,_Key_equality), a)
+    {
+        insert(first, last);
+    }
+
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Constructor from initializer_list
+    concurrent_unordered_multimap(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
+    {
+        this->insert(il.begin(),il.end());
+    }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+    concurrent_unordered_multimap(const concurrent_unordered_multimap& table)
+        : base_type(table)
+    {
+    }
+
+    concurrent_unordered_multimap& operator=(const concurrent_unordered_multimap& table)
+    {
+        return static_cast<concurrent_unordered_multimap&>(base_type::operator=(table));
+    }
+
+    concurrent_unordered_multimap(concurrent_unordered_multimap&& table)
+        : base_type(std::move(table))
+    {
+    }
+
+    concurrent_unordered_multimap& operator=(concurrent_unordered_multimap&& table)
+    {
+        return static_cast<concurrent_unordered_multimap&>(base_type::operator=(std::move(table)));
+    }
+#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+
+    concurrent_unordered_multimap(const concurrent_unordered_multimap& table, const Allocator& a)
+        : base_type(table, a)
+    {
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    concurrent_unordered_multimap(concurrent_unordered_multimap&& table, const Allocator& a) : base_type(std::move(table), a)
+    {
+    }
+#endif
+};
 } // namespace interface5
 
 using interface5::concurrent_unordered_map;
+using interface5::concurrent_unordered_multimap;
 
 } // namespace tbb
 
index 45b550e1ccbeb908121d2d09975b270ea792fd91..846351869eb155f70938b1e31a1bd8724b32de91 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 /* Container implementations in this header are based on PPL implementations
@@ -69,14 +61,11 @@ class concurrent_unordered_set : public internal::concurrent_unordered_base< con
     typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
     typedef internal::concurrent_unordered_base< concurrent_unordered_set_traits<Key, hash_compare, Allocator, false> > base_type;
     typedef concurrent_unordered_set_traits<Key, internal::hash_compare<Key, Hasher, Key_equality>, Allocator, false> traits_type;
-    using traits_type::my_hash_compare;
 #if __TBB_EXTRA_DEBUG
 public:
 #endif
     using traits_type::allow_multimapping;
 public:
-    using base_type::end;
-    using base_type::find;
     using base_type::insert;
 
     // Type definitions
@@ -102,75 +91,178 @@ public:
     typedef typename base_type::const_iterator const_local_iterator;
 
     // Construction/destruction/copying
-    explicit concurrent_unordered_set(size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
+    explicit concurrent_unordered_set(size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(),
         const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
         : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
     {
     }
 
-    concurrent_unordered_set(const Allocator& a) : base_type(8, key_compare(), a)
+    concurrent_unordered_set(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
     {
     }
 
     template <typename Iterator>
-    concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = 8, const hasher& a_hasher = hasher(),
+    concurrent_unordered_set(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(),
         const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
         : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
     {
-        for (; first != last; ++first)
-            base_type::insert(*first);
+        insert(first, last);
     }
 
-    concurrent_unordered_set(const concurrent_unordered_set& table) : base_type(table)
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Constructor from initializer_list
+   concurrent_unordered_set(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(),
+        const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
+    {
+        this->insert(il.begin(),il.end());
+    }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+    concurrent_unordered_set(const concurrent_unordered_set& table)
+        : base_type(table)
+    {
+    }
+
+    concurrent_unordered_set& operator=(const concurrent_unordered_set& table)
     {
+        return static_cast<concurrent_unordered_set&>(base_type::operator=(table));
     }
 
+    concurrent_unordered_set(concurrent_unordered_set&& table)
+        : base_type(std::move(table))
+    {
+    }
+
+    concurrent_unordered_set& operator=(concurrent_unordered_set&& table)
+    {
+        return static_cast<concurrent_unordered_set&>(base_type::operator=(std::move(table)));
+    }
+#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+
     concurrent_unordered_set(const concurrent_unordered_set& table, const Allocator& a)
         : base_type(table, a)
     {
     }
 
-    concurrent_unordered_set& operator=(const concurrent_unordered_set& table)
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    concurrent_unordered_set(concurrent_unordered_set&& table, const Allocator& a)
+        : base_type(std::move(table), a)
+    {
+    }
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
+};
+
+template <typename Key, typename Hasher = tbb::tbb_hash<Key>, typename Key_equality = std::equal_to<Key>,
+         typename Allocator = tbb::tbb_allocator<Key> >
+class concurrent_unordered_multiset :
+    public internal::concurrent_unordered_base< concurrent_unordered_set_traits<Key,
+    internal::hash_compare<Key, Hasher, Key_equality>, Allocator, true> >
+{
+    // Base type definitions
+    typedef internal::hash_compare<Key, Hasher, Key_equality> hash_compare;
+    typedef concurrent_unordered_set_traits<Key, hash_compare, Allocator, true> traits_type;
+    typedef internal::concurrent_unordered_base< traits_type > base_type;
+#if __TBB_EXTRA_DEBUG
+public:
+#endif
+    using traits_type::allow_multimapping;
+public:
+    using base_type::insert;
+
+    // Type definitions
+    typedef Key key_type;
+    typedef typename base_type::value_type value_type;
+    typedef Key mapped_type;
+    typedef Hasher hasher;
+    typedef Key_equality key_equal;
+    typedef hash_compare key_compare;
+
+    typedef typename base_type::allocator_type allocator_type;
+    typedef typename base_type::pointer pointer;
+    typedef typename base_type::const_pointer const_pointer;
+    typedef typename base_type::reference reference;
+    typedef typename base_type::const_reference const_reference;
+
+    typedef typename base_type::size_type size_type;
+    typedef typename base_type::difference_type difference_type;
+
+    typedef typename base_type::iterator iterator;
+    typedef typename base_type::const_iterator const_iterator;
+    typedef typename base_type::iterator local_iterator;
+    typedef typename base_type::const_iterator const_local_iterator;
+
+    // Construction/destruction/copying
+    explicit concurrent_unordered_multiset(size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
     {
-        base_type::operator=(table);
-        return (*this);
     }
 
-    iterator unsafe_erase(const_iterator where)
+    concurrent_unordered_multiset(const Allocator& a) : base_type(base_type::initial_bucket_number, key_compare(), a)
     {
-        return base_type::unsafe_erase(where);
     }
 
-    size_type unsafe_erase(const key_type& key)
+    template <typename Iterator>
+    concurrent_unordered_multiset(Iterator first, Iterator last, size_type n_of_buckets = base_type::initial_bucket_number,
+        const hasher& _Hasher = hasher(), const key_equal& _Key_equality = key_equal(),
+        const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(_Hasher, _Key_equality), a)
     {
-        return base_type::unsafe_erase(key);
+        insert(first, last);
     }
 
-    iterator unsafe_erase(const_iterator first, const_iterator last)
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Constructor from initializer_list
+   concurrent_unordered_multiset(std::initializer_list<value_type> il, size_type n_of_buckets = base_type::initial_bucket_number, const hasher& a_hasher = hasher(),
+        const key_equal& a_keyeq = key_equal(), const allocator_type& a = allocator_type())
+        : base_type(n_of_buckets, key_compare(a_hasher, a_keyeq), a)
     {
-        return base_type::unsafe_erase(first, last);
+        this->insert(il.begin(),il.end());
     }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT    
 
-    void swap(concurrent_unordered_set& table)
+#if __TBB_CPP11_RVALUE_REF_PRESENT && __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+   concurrent_unordered_multiset(const concurrent_unordered_multiset& table)
+        : base_type(table)
     {
-        base_type::swap(table);
     }
 
-    // Observers
-    hasher hash_function() const
+   concurrent_unordered_multiset& operator=(const concurrent_unordered_multiset& table)
     {
-        return my_hash_compare.my_hash_object;
+        return static_cast<concurrent_unordered_multiset&>(base_type::operator=(table));
     }
 
-    key_equal key_eq() const
+   concurrent_unordered_multiset(concurrent_unordered_multiset&& table)
+        : base_type(std::move(table))
     {
-        return my_hash_compare.my_key_compare_object;
     }
-};
 
+   concurrent_unordered_multiset& operator=(concurrent_unordered_multiset&& table)
+    {
+        return static_cast<concurrent_unordered_multiset&>(base_type::operator=(std::move(table)));
+    }
+#endif //__TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN
+
+    concurrent_unordered_multiset(const concurrent_unordered_multiset& table, const Allocator& a)
+        : base_type(table, a)
+    {
+    }
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    concurrent_unordered_multiset(concurrent_unordered_multiset&& table, const Allocator& a)
+        : base_type(std::move(table), a)
+    {
+    }
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+};
 } // namespace interface5
 
 using interface5::concurrent_unordered_set;
+using interface5::concurrent_unordered_multiset;
 
 } // namespace tbb
 
index b7df14bc70fc5d382e78daa7ce703160323e4745..bdecd7ef700cb4b1634fb099901deaf668bcf04f 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_concurrent_vector_H
     #pragma warning( pop )
 #endif
 
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_Wp64)
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    #include <initializer_list>
+#endif
+
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
     // Workaround for overzealous compiler warnings in /Wp64 mode
     #pragma warning (push)
+#if defined(_Wp64)
     #pragma warning (disable: 4267)
 #endif
+    #pragma warning (disable: 4127) //warning C4127: conditional expression is constant
+#endif
 
 namespace tbb {
 
 template<typename T, class A = cache_aligned_allocator<T> >
 class concurrent_vector;
 
+template<typename Container, typename Value>
+class vector_iterator;
+
 //! @cond INTERNAL
 namespace internal {
 
     //! Bad allocation marker
     static void *const vector_allocation_error_flag = reinterpret_cast<void*>(size_t(63));
 
+    //! Exception helper function
+    template<typename T>
+    void handle_unconstructed_elements(T* array, size_t n_of_elements){
+        std::memset(array, 0, n_of_elements * sizeof(T));
+    }
+
     //! Base class of concurrent vector implementation.
     /** @ingroup containers */
     class concurrent_vector_base_v3 {
@@ -92,21 +100,81 @@ namespace internal {
         enum {
             // Size constants
             default_initial_segments = 1, // 2 initial items
-            //! Number of slots for segment's pointers inside the class
+            //! Number of slots for segment pointers inside the class
             pointers_per_short_table = 3, // to fit into 8 words of entire structure
             pointers_per_long_table = sizeof(segment_index_t) * 8 // one segment per bit
         };
 
-        // Segment pointer. Can be zero-initialized
-        struct segment_t {
+        struct segment_not_used {};
+        struct segment_allocated {};
+        struct segment_allocation_failed {};
+
+        class segment_t;
+        class segment_value_t {
             void* array;
+        private:
+            //TODO: More elegant way to grant access to selected functions _only_?
+            friend class segment_t;
+            explicit segment_value_t(void* an_array):array(an_array) {}
+        public:
+            friend bool operator==(segment_value_t const& lhs, segment_not_used ) { return lhs.array == 0;}
+            friend bool operator==(segment_value_t const& lhs, segment_allocated) { return lhs.array > internal::vector_allocation_error_flag;}
+            friend bool operator==(segment_value_t const& lhs, segment_allocation_failed) { return lhs.array == internal::vector_allocation_error_flag;}
+            template<typename argument_type>
+            friend bool operator!=(segment_value_t const& lhs, argument_type arg) { return ! (lhs == arg);}
+
+            template<typename T>
+            T* pointer() const {  return static_cast<T*>(const_cast<void*>(array)); }
+        };
+
+        // Segment pointer.
+        class segment_t {
+            atomic<void*> array;
+        public:
+            segment_t(){ store<relaxed>(segment_not_used());}
+            //Copy ctor and assignment operator are defined to ease using of stl algorithms.
+            //These algorithms usually not a synchronization point, so, semantic is
+            //intentionally relaxed here.
+            segment_t(segment_t const& rhs ){ array.store<relaxed>(rhs.array.load<relaxed>());}
+
+            void swap(segment_t & rhs ){
+                tbb::internal::swap<relaxed>(array, rhs.array);
+            }
+
+            segment_t& operator=(segment_t const& rhs ){
+                array.store<relaxed>(rhs.array.load<relaxed>());
+                return *this;
+            }
+
+            template<memory_semantics M>
+            segment_value_t load() const { return segment_value_t(array.load<M>());}
+
+            template<memory_semantics M>
+            void store(segment_not_used) {
+                array.store<M>(0);
+            }
+
+            template<memory_semantics M>
+            void store(segment_allocation_failed) {
+                __TBB_ASSERT(load<relaxed>() != segment_allocated(),"transition from \"allocated\" to \"allocation failed\" state looks non-logical");
+                array.store<M>(internal::vector_allocation_error_flag);
+            }
+
+            template<memory_semantics M>
+            void store(void* allocated_segment_pointer) __TBB_NOEXCEPT(true) {
+                __TBB_ASSERT(segment_value_t(allocated_segment_pointer) == segment_allocated(),
+                     "other overloads of store should be used for marking segment as not_used or allocation_failed" );
+                array.store<M>(allocated_segment_pointer);
+            }
+
 #if TBB_USE_ASSERT
             ~segment_t() {
-                __TBB_ASSERT( array <= internal::vector_allocation_error_flag, "should have been freed by clear" );
+                __TBB_ASSERT(load<relaxed>() != segment_allocated(), "should have been freed by clear" );
             }
 #endif /* TBB_USE_ASSERT */
         };
+        friend void swap(segment_t & , segment_t & ) __TBB_NOEXCEPT(true);
+
         // Data fields
 
         //! allocator function pointer
@@ -127,14 +195,25 @@ namespace internal {
         // Methods
 
         concurrent_vector_base_v3() {
-            my_early_size = 0;
-            my_first_block = 0; // here is not default_initial_segments
-            for( segment_index_t i = 0; i < pointers_per_short_table; i++)
-                my_storage[i].array = NULL;
-            my_segment = my_storage;
+            //Here the semantic is intentionally relaxed.
+            //The reason this is next:
+            //Object that is in middle of construction (i.e. its constructor is not yet finished)
+            //cannot be used concurrently until the construction is finished.
+            //Thus to flag other threads that construction is finished, some synchronization with
+            //acquire-release semantic should be done by the (external) code that uses the vector.
+            //So, no need to do the synchronization inside the vector.
+
+            my_early_size.store<relaxed>(0);
+            my_first_block.store<relaxed>(0); // here is not default_initial_segments
+            my_segment.store<relaxed>(my_storage);
         }
+
         __TBB_EXPORTED_METHOD ~concurrent_vector_base_v3();
 
+        //these helpers methods use the fact that segments are allocated so
+        //that every segment size is a (increasing) power of 2.
+        //with one exception 0 segment has size of 2 as well segment 1;
+        //e.g. size of segment with index of 3 is 2^3=8;
         static segment_index_t segment_index_of( size_type index ) {
             return segment_index_t( __TBB_Log2( index|1 ) );
         }
@@ -153,6 +232,16 @@ namespace internal {
             return segment_index_t(1)<<k; // fake value for k==0
         }
 
+
+        static bool is_first_element_in_segment(size_type element_index){
+            //check if element_index is a power of 2 that is at least 2.
+            //The idea is to detect if the iterator crosses a segment boundary,
+            //and 2 is the minimal index for which it's true
+            __TBB_ASSERT(element_index, "there should be no need to call "
+                                        "is_first_element_in_segment for 0th element" );
+            return is_power_of_two_factor( element_index, 2 );
+        }
+
         //! An operation on an n-element array starting at begin.
         typedef void (__TBB_EXPORTED_FUNC *internal_array_op1)(void* begin, size_type n );
 
@@ -162,7 +251,7 @@ namespace internal {
         //! Internal structure for compact()
         struct internal_segments_table {
             segment_index_t first_block;
-            void* table[pointers_per_long_table];
+            segment_t table[pointers_per_long_table];
         };
 
         void __TBB_EXPORTED_METHOD internal_reserve( size_type n, size_type element_size, size_type max_size );
@@ -189,20 +278,28 @@ private:
         //! Private functionality
         class helper;
         friend class helper;
+
+        template<typename Container, typename Value>
+        friend class vector_iterator;
+
     };
-    
+
+    inline void swap(concurrent_vector_base_v3::segment_t & lhs, concurrent_vector_base_v3::segment_t & rhs) __TBB_NOEXCEPT(true) {
+        lhs.swap(rhs);
+    }
+
     typedef concurrent_vector_base_v3 concurrent_vector_base;
 
     //! Meets requirements of a forward iterator for STL and a Value for a blocked_range.*/
     /** Value is either the T or const T type of the container.
         @ingroup containers */
     template<typename Container, typename Value>
-    class vector_iterator 
+    class vector_iterator
     {
         //! concurrent_vector over which we are iterating.
         Container* my_vector;
 
-        //! Index into the vector 
+        //! Index into the vector
         size_t my_index;
 
         //! Caches my_vector-&gt;internal_subscript(my_index)
@@ -220,20 +317,20 @@ private:
 
         template<typename C, typename T, typename U>
         friend ptrdiff_t operator-( const vector_iterator<C,T>& i, const vector_iterator<C,U>& j );
-    
+
         template<typename C, typename U>
         friend class internal::vector_iterator;
 
-#if !defined(_MSC_VER) || defined(__INTEL_COMPILER)
+#if !__TBB_TEMPLATE_FRIENDS_BROKEN
         template<typename T, class A>
         friend class tbb::concurrent_vector;
 #else
-public: // workaround for MSVC
-#endif 
+public:
+#endif
 
-        vector_iterator( const Container& vector, size_t index, void *ptr = 0 ) : 
-            my_vector(const_cast<Container*>(&vector)), 
-            my_index(index), 
+        vector_iterator( const Container& vector, size_t index, void *ptr = 0 ) :
+            my_vector(const_cast<Container*>(&vector)),
+            my_index(index),
             my_item(static_cast<Value*>(ptr))
         {}
 
@@ -278,11 +375,12 @@ public: // workaround for MSVC
 
         //! Pre increment
         vector_iterator& operator++() {
-            size_t k = ++my_index;
+            size_t element_index = ++my_index;
             if( my_item ) {
-                // Following test uses 2's-complement wizardry
-                if( (k& (k-2))==0 ) {
-                    // k is a power of two that is at least k-2
+                //TODO: consider using of knowledge about "first_block optimization" here as well?
+                if( concurrent_vector_base::is_first_element_in_segment(element_index)) {
+                    //if the iterator crosses a segment boundary, the pointer become invalid
+                    //as possibly next segment is in another memory location
                     my_item= NULL;
                 } else {
                     ++my_item;
@@ -293,12 +391,12 @@ public: // workaround for MSVC
 
         //! Pre decrement
         vector_iterator& operator--() {
-            __TBB_ASSERT( my_index>0, "operator--() applied to iterator already at beginning of concurrent_vector" ); 
-            size_t k = my_index--;
+            __TBB_ASSERT( my_index>0, "operator--() applied to iterator already at beginning of concurrent_vector" );
+            size_t element_index = my_index--;
             if( my_item ) {
-                // Following test uses 2's-complement wizardry
-                if( (k& (k-2))==0 ) {
-                    // k is a power of two that is at least k-2  
+                if(concurrent_vector_base::is_first_element_in_segment(element_index)) {
+                    //if the iterator crosses a segment boundary, the pointer become invalid
+                    //as possibly next segment is in another memory location
                     my_item= NULL;
                 } else {
                     --my_item;
@@ -378,6 +476,7 @@ public: // workaround for MSVC
         allocator_type my_allocator;
 
         allocator_base(const allocator_type &a = allocator_type() ) : my_allocator(a) {}
+
     };
 
 } // namespace internal
@@ -405,7 +504,7 @@ public: // workaround for MSVC
 @par
     If an exception happens inside growth or assignment operation, an instance of the vector becomes invalid unless it is stated otherwise in the method documentation.
     Invalid state means:
-    - There are no guaranties that all items were initialized by a constructor. The rest of items is zero-filled, including item where exception happens.
+    - There are no guarantees that all items were initialized by a constructor. The rest of items is zero-filled, including item where exception happens.
     - An invalid vector instance cannot be repaired; it is unable to grow anymore.
     - Size and capacity reported by the vector are incorrect, and calculated as if the failed operation were successful.
     - Attempt to access not allocated elements using operator[] or iterators results in access violation or segmentation fault exception, and in case of using at() method a C++ exception is thrown.
@@ -428,13 +527,13 @@ public: // workaround for MSVC
     - Changed return type of methods grow* and push_back to iterator
 
 @par Changes since TBB 2.0
-    - Implemented exception-safety guaranties
+    - Implemented exception-safety guarantees
     - Added template argument for allocator
     - Added allocator argument in constructors
     - Faster index calculation
     - First growth call specifies a number of segments to be merged in the first allocation.
     - Fixed memory blow up for swarm of vector's instances of small size
-    - Added grow_by(size_type n, const_reference t) growth using copying constructor to init new items. 
+    - Added grow_by(size_type n, const_reference t) growth using copying constructor to init new items.
     - Added STL-like constructors.
     - Added operators ==, < and derivatives
     - Added at() method, approved for using after an exception was thrown inside the vector
@@ -442,7 +541,7 @@ public: // workaround for MSVC
     - Added assign() methods
     - Added compact() method to defragment first segments
     - Added swap() method
-    - range() defaults on grainsize = 1 supporting auto grainsize algorithms. 
+    - range() defaults on grainsize = 1 supporting auto grainsize algorithms.
 
     @ingroup containers */
 template<typename T, class A>
@@ -457,14 +556,15 @@ private:
         typedef const T& const_reference;
         typedef I iterator;
         typedef ptrdiff_t difference_type;
-        generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range<I>(begin_,end_,grainsize_) {} 
+        generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range<I>(begin_,end_,grainsize_) {}
         template<typename U>
-        generic_range_type( const generic_range_type<U>& r) : blocked_range<I>(r.begin(),r.end(),r.grainsize()) {} 
+        generic_range_type( const generic_range_type<U>& r) : blocked_range<I>(r.begin(),r.end(),r.grainsize()) {}
         generic_range_type( generic_range_type& r, split ) : blocked_range<I>(r,split()) {}
     };
 
     template<typename C, typename U>
     friend class internal::vector_iterator;
+
 public:
     //------------------------------------------------------------------------
     // STL compatible types
@@ -482,7 +582,7 @@ public:
     typedef internal::vector_iterator<concurrent_vector,T> iterator;
     typedef internal::vector_iterator<concurrent_vector,const T> const_iterator;
 
-#if !defined(_MSC_VER) || _CPPLIB_VER>=300 
+#if !defined(_MSC_VER) || _CPPLIB_VER>=300
     // Assume ISO standard definition of std::reverse_iterator
     typedef std::reverse_iterator<iterator> reverse_iterator;
     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
@@ -509,6 +609,25 @@ public:
         vector_allocator_ptr = &internal_allocator;
     }
 
+    //Constructors are not required to have synchronization
+    //(for more details see comment in the concurrent_vector_base constructor).
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Constructor from initializer_list
+    concurrent_vector(std::initializer_list<T> init_list, const allocator_type &a = allocator_type())
+        : internal::allocator_base<T, A>(a), internal::concurrent_vector_base()
+    {
+        vector_allocator_ptr = &internal_allocator;
+        __TBB_TRY {
+            internal_assign_iterators(init_list.begin(), init_list.end());
+        } __TBB_CATCH(...) {
+            segment_t *table = my_segment.load<relaxed>();;
+            internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>());
+            __TBB_RETHROW();
+        }
+
+    }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
+
     //! Copying constructor
     concurrent_vector( const concurrent_vector& vector, const allocator_type& a = allocator_type() )
         : internal::allocator_base<T, A>(a), internal::concurrent_vector_base()
@@ -517,12 +636,43 @@ public:
         __TBB_TRY {
             internal_copy(vector, sizeof(T), &copy_array);
         } __TBB_CATCH(...) {
-            segment_t *table = my_segment;
-            internal_free_segments( reinterpret_cast<void**>(table), internal_clear(&destroy_array), my_first_block );
+            segment_t *table = my_segment.load<relaxed>();
+            internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>());
             __TBB_RETHROW();
         }
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move constructor
+    //TODO add __TBB_NOEXCEPT(true) and static_assert(std::has_nothrow_move_constructor<A>::value)
+    concurrent_vector( concurrent_vector&& source)
+        : internal::allocator_base<T, A>(std::move(source)), internal::concurrent_vector_base()
+    {
+        vector_allocator_ptr = &internal_allocator;
+        concurrent_vector_base_v3::internal_swap(source);
+    }
+
+    concurrent_vector( concurrent_vector&& source, const allocator_type& a)
+        : internal::allocator_base<T, A>(a), internal::concurrent_vector_base()
+    {
+        vector_allocator_ptr = &internal_allocator;
+        //C++ standard requires instances of an allocator being compared for equality,
+        //which means that memory allocated by one instance is possible to deallocate with the other one.
+        if (a == source.my_allocator) {
+            concurrent_vector_base_v3::internal_swap(source);
+        } else {
+            __TBB_TRY {
+                internal_copy(source, sizeof(T), &move_array);
+            } __TBB_CATCH(...) {
+                segment_t *table = my_segment.load<relaxed>();
+                internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>());
+                __TBB_RETHROW();
+            }
+        }
+    }
+
+#endif
+
     //! Copying constructor for vector with different allocator type
     template<class M>
     concurrent_vector( const concurrent_vector<T, M>& vector, const allocator_type& a = allocator_type() )
@@ -532,8 +682,8 @@ public:
         __TBB_TRY {
             internal_copy(vector.internal_vector_base(), sizeof(T), &copy_array);
         } __TBB_CATCH(...) {
-            segment_t *table = my_segment;
-            internal_free_segments( reinterpret_cast<void**>(table), internal_clear(&destroy_array), my_first_block );
+            segment_t *table = my_segment.load<relaxed>();
+            internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>() );
             __TBB_RETHROW();
         }
     }
@@ -545,8 +695,8 @@ public:
         __TBB_TRY {
             internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array );
         } __TBB_CATCH(...) {
-            segment_t *table = my_segment;
-            internal_free_segments( reinterpret_cast<void**>(table), internal_clear(&destroy_array), my_first_block );
+            segment_t *table = my_segment.load<relaxed>();
+            internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>() );
             __TBB_RETHROW();
         }
     }
@@ -559,8 +709,8 @@ public:
         __TBB_TRY {
             internal_resize( n, sizeof(T), max_size(), static_cast<const void*>(&t), &destroy_array, &initialize_array_by );
         } __TBB_CATCH(...) {
-            segment_t *table = my_segment;
-            internal_free_segments( reinterpret_cast<void**>(table), internal_clear(&destroy_array), my_first_block );
+            segment_t *table = my_segment.load<relaxed>();
+            internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>() );
             __TBB_RETHROW();
         }
     }
@@ -574,8 +724,8 @@ public:
         __TBB_TRY {
             internal_assign_range(first, last, static_cast<is_integer_tag<std::numeric_limits<I>::is_integer> *>(0) );
         } __TBB_CATCH(...) {
-            segment_t *table = my_segment;
-            internal_free_segments( reinterpret_cast<void**>(table), internal_clear(&destroy_array), my_first_block );
+            segment_t *table = my_segment.load<relaxed>();
+            internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>() );
             __TBB_RETHROW();
         }
     }
@@ -587,6 +737,26 @@ public:
         return *this;
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //TODO: add __TBB_NOEXCEPT()
+    //! Move assignment
+    concurrent_vector& operator=( concurrent_vector&& other ) {
+        __TBB_ASSERT(this != &other, "Move assignment to itself is prohibited ");
+        typedef typename tbb::internal::allocator_traits<A>::propagate_on_container_move_assignment pocma_t;
+        if(pocma_t::value || this->my_allocator == other.my_allocator) {
+            concurrent_vector trash (std::move(*this));
+            internal_swap(other);
+            if (pocma_t::value) {
+                this->my_allocator = std::move(other.my_allocator);
+            }
+        } else {
+            internal_assign(other, sizeof(T), &destroy_array, &move_assign_array, &move_array);
+        }
+        return *this;
+    }
+#endif
+    //TODO: add an template assignment operator? (i.e. with different element type)
+
     //! Assignment for vector with different allocator type
     template<class M>
     concurrent_vector& operator=( const concurrent_vector<T, M>& vector ) {
@@ -596,43 +766,47 @@ public:
         return *this;
     }
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Assignment for initializer_list
+    concurrent_vector& operator=( std::initializer_list<T> init_list ) {
+        internal_clear(&destroy_array);
+        internal_assign_iterators(init_list.begin(), init_list.end());
+        return *this;
+    }
+#endif //#if __TBB_INITIALIZER_LISTS_PRESENT
+
     //------------------------------------------------------------------------
     // Concurrent operations
     //------------------------------------------------------------------------
     //! Grow by "delta" elements.
-#if TBB_DEPRECATED
-    /** Returns old size. */
-    size_type grow_by( size_type delta ) {
-        return delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size;
-    }
-#else
     /** Returns iterator pointing to the first new element. */
     iterator grow_by( size_type delta ) {
-        return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size);
+        return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array, NULL ) : my_early_size.load());
     }
-#endif
 
-    //! Grow by "delta" elements using copying constuctor.
-#if TBB_DEPRECATED
-    /** Returns old size. */
-    size_type grow_by( size_type delta, const_reference t ) {
-        return delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast<const void*>(&t) ) : my_early_size;
-    }
-#else
+    //! Grow by "delta" elements using copying constructor.
     /** Returns iterator pointing to the first new element. */
     iterator grow_by( size_type delta, const_reference t ) {
-        return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast<const void*>(&t) ) : my_early_size);
+        return iterator(*this, delta ? internal_grow_by( delta, sizeof(T), &initialize_array_by, static_cast<const void*>(&t) ) : my_early_size.load());
     }
-#endif
 
-    //! Append minimal sequence of elements such that size()>=n.  
-#if TBB_DEPRECATED
-    /** The new elements are default constructed.  Blocks until all elements in range [0..n) are allocated.
-        May return while other elements are being constructed by other threads. */
-    void grow_to_at_least( size_type n ) {
-        if( n ) internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array, NULL );
-    };
-#else
+    /** Returns iterator pointing to the first new element. */
+    template<typename I>
+    iterator grow_by( I first, I last ) {
+        typename std::iterator_traits<I>::difference_type delta = std::distance(first, last);
+        __TBB_ASSERT( delta >= 0, NULL);
+
+        return iterator(*this, delta ? internal_grow_by(delta, sizeof(T), &copy_range<I>, static_cast<const void*>(&first)) : my_early_size.load());
+    }
+
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    /** Returns iterator pointing to the first new element. */
+    iterator grow_by( std::initializer_list<T> init_list ) {
+        return grow_by( init_list.begin(), init_list.end() );
+    }
+#endif //#if __TBB_INITIALIZER_LISTS_PRESENT
+
+    //! Append minimal sequence of elements such that size()>=n.
     /** The new elements are default constructed.  Blocks until all elements in range [0..n) are allocated.
         May return while other elements are being constructed by other threads.
         Returns iterator that points to beginning of appended sequence.
@@ -645,30 +819,51 @@ public:
         }
         return iterator(*this, m);
     };
-#endif
 
-    //! Push item 
-#if TBB_DEPRECATED
-    size_type push_back( const_reference item )
-#else
+    /** Analogous to grow_to_at_least( size_type n ) with exception that the new
+        elements are initialized by copying of t instead of default construction. */
+    iterator grow_to_at_least( size_type n, const_reference t ) {
+        size_type m=0;
+        if( n ) {
+            m = internal_grow_to_at_least_with_result( n, sizeof(T), &initialize_array_by, &t);
+            if( m>n ) m=n;
+        }
+        return iterator(*this, m);
+    };
+
+    //! Push item
     /** Returns iterator pointing to the new element. */
     iterator push_back( const_reference item )
-#endif
     {
-        size_type k;
-        void *ptr = internal_push_back(sizeof(T),k);
-        internal_loop_guide loop(1, ptr);
-        loop.init(&item);
-#if TBB_DEPRECATED
-        return k;
-#else
-        return iterator(*this, k, ptr);
-#endif
+        push_back_helper prolog(*this);
+        new(prolog.internal_push_back_result()) T(item);
+        return prolog.return_iterator_and_dismiss();
     }
 
+#if    __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Push item, move-aware
+    /** Returns iterator pointing to the new element. */
+    iterator push_back(  T&& item )
+    {
+        push_back_helper prolog(*this);
+        new(prolog.internal_push_back_result()) T(std::move(item));
+        return prolog.return_iterator_and_dismiss();
+    }
+#if __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+    //! Push item, create item "in place" with provided arguments
+    /** Returns iterator pointing to the new element. */
+    template<typename... Args>
+    iterator emplace_back(  Args&&... args )
+    {
+        push_back_helper prolog(*this);
+        new(prolog.internal_push_back_result()) T(std::forward<Args>(args)...);
+        return prolog.return_iterator_and_dismiss();
+    }
+#endif //__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
     //! Get reference to element at given index.
     /** This method is thread-safe for concurrent reads, and also while growing the vector,
-        as long as the calling thread has checked that index&lt;size(). */
+        as long as the calling thread has checked that index < size(). */
     reference operator[]( size_type index ) {
         return internal_subscript(index);
     }
@@ -689,7 +884,7 @@ public:
     }
 
     //! Get range for iterating with parallel algorithms
-    range_type range( size_t grainsize = 1) {
+    range_type range( size_t grainsize = 1 ) {
         return range_type( begin(), end(), grainsize );
     }
 
@@ -697,6 +892,7 @@ public:
     const_range_type range( size_t grainsize = 1 ) const {
         return const_range_type( begin(), end(), grainsize );
     }
+
     //------------------------------------------------------------------------
     // Capacity
     //------------------------------------------------------------------------
@@ -713,7 +909,7 @@ public:
     size_type capacity() const {return internal_capacity();}
 
     //! Allocate enough space to grow to size n without having to allocate more memory later.
-    /** Like most of the methods provided for STL compatibility, this method is *not* thread safe. 
+    /** Like most of the methods provided for STL compatibility, this method is *not* thread safe.
         The capacity afterwards may be bigger than the requested reservation. */
     void reserve( size_type n ) {
         if( n )
@@ -724,16 +920,11 @@ public:
     void resize( size_type n ) {
         internal_resize( n, sizeof(T), max_size(), NULL, &destroy_array, &initialize_array );
     }
-    
+
     //! Resize the vector, copy t for new elements. Not thread-safe.
     void resize( size_type n, const_reference t ) {
         internal_resize( n, sizeof(T), max_size(), static_cast<const void*>(&t), &destroy_array, &initialize_array_by );
     }
-   
-#if TBB_DEPRECATED 
-    //! An alias for shrink_to_fit()
-    void compact() {shrink_to_fit();}
-#endif /* TBB_DEPRECATED */
 
     //! Optimize memory usage and fragmentation.
     void shrink_to_fit();
@@ -772,7 +963,7 @@ public:
     //! the first item
     reference front() {
         __TBB_ASSERT( size()>0, NULL);
-        return static_cast<T*>(my_segment[0].array)[0];
+        return (my_segment[0].template load<relaxed>().template pointer<T>())[0];
     }
     //! the first item const
     const_reference front() const {
@@ -804,11 +995,19 @@ public:
         clear(); internal_assign_range( first, last, static_cast<is_integer_tag<std::numeric_limits<I>::is_integer> *>(0) );
     }
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! assigns an initializer list
+    void assign(std::initializer_list<T> init_list) {
+        clear(); internal_assign_iterators( init_list.begin(), init_list.end());
+    }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
+
     //! swap two instances
     void swap(concurrent_vector &vector) {
+        using std::swap;
         if( this != &vector ) {
             concurrent_vector_base_v3::internal_swap(static_cast<concurrent_vector_base_v3&>(vector));
-            std::swap(this->my_allocator, vector.my_allocator);
+            swap(this->my_allocator, vector.my_allocator);
         }
     }
 
@@ -820,8 +1019,8 @@ public:
 
     //! Clear and destroy vector.
     ~concurrent_vector() {
-        segment_t *table = my_segment;
-        internal_free_segments( reinterpret_cast<void**>(table), internal_clear(&destroy_array), my_first_block );
+        segment_t *table = my_segment.load<relaxed>();
+        internal_free_segments( table, internal_clear(&destroy_array), my_first_block.load<relaxed>() );
         // base class destructor call should be then
     }
 
@@ -832,7 +1031,7 @@ private:
         return static_cast<concurrent_vector<T, A>&>(vb).my_allocator.allocate(k);
     }
     //! Free k segments from table
-    void internal_free_segments(void *table[], segment_index_t k, segment_index_t first_block);
+    void internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block);
 
     //! Get reference to element at given index.
     T& internal_subscript( size_type index ) const;
@@ -862,16 +1061,34 @@ private:
     template<class I>
     void internal_assign_iterators(I first, I last);
 
+    //these functions are marked __TBB_EXPORTED_FUNC as they are called from within the library
+
     //! Construct n instances of T, starting at "begin".
     static void __TBB_EXPORTED_FUNC initialize_array( void* begin, const void*, size_type n );
 
-    //! Construct n instances of T, starting at "begin".
+    //! Copy-construct n instances of T, starting at "begin".
     static void __TBB_EXPORTED_FUNC initialize_array_by( void* begin, const void* src, size_type n );
 
-    //! Construct n instances of T, starting at "begin".
+    //! Copy-construct n instances of T by copying single element pointed to by src, starting at "dst".
     static void __TBB_EXPORTED_FUNC copy_array( void* dst, const void* src, size_type n );
 
-    //! Assign n instances of T, starting at "begin".
+#if __TBB_MOVE_IF_NOEXCEPT_PRESENT
+    //! Either opy or move-construct n instances of T, starting at "dst" by copying according element of src array.
+    static void __TBB_EXPORTED_FUNC move_array_if_noexcept( void* dst, const void* src, size_type n );
+#endif //__TBB_MOVE_IF_NO_EXCEPT_PRESENT
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! Move-construct n instances of T, starting at "dst" by copying according element of src array.
+    static void __TBB_EXPORTED_FUNC move_array( void* dst, const void* src, size_type n );
+
+    //! Move-assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array.
+    static void __TBB_EXPORTED_FUNC move_assign_array( void* dst, const void* src, size_type n );
+#endif
+    //! Copy-construct n instances of T, starting at "dst" by iterator range of [p_type_erased_iterator, p_type_erased_iterator+n).
+    template<typename Iterator>
+    static void __TBB_EXPORTED_FUNC copy_range( void* dst, const void* p_type_erased_iterator, size_type n );
+
+    //! Assign (using operator=) n instances of T, starting at "dst" by assigning according element of src array.
     static void __TBB_EXPORTED_FUNC assign_array( void* dst, const void* src, size_type n );
 
     //! Destroy n instances of T, starting at "begin".
@@ -883,21 +1100,64 @@ private:
         const pointer array;
         const size_type n;
         size_type i;
+
+        static const T* as_const_pointer(const void *ptr) { return static_cast<const T *>(ptr); }
+        static T* as_pointer(const void *src) { return static_cast<T*>(const_cast<void *>(src)); }
+
         internal_loop_guide(size_type ntrials, void *ptr)
-            : array(static_cast<pointer>(ptr)), n(ntrials), i(0) {}
+            : array(as_pointer(ptr)), n(ntrials), i(0) {}
         void init() {   for(; i < n; ++i) new( &array[i] ) T(); }
-        void init(const void *src) { for(; i < n; ++i) new( &array[i] ) T(*static_cast<const T*>(src)); }
-        void copy(const void *src) { for(; i < n; ++i) new( &array[i] ) T(static_cast<const T*>(src)[i]); }
-        void assign(const void *src) { for(; i < n; ++i) array[i] = static_cast<const T*>(src)[i]; }
+        void init(const void *src) { for(; i < n; ++i) new( &array[i] ) T(*as_const_pointer(src)); }
+        void copy(const void *src) { for(; i < n; ++i) new( &array[i] ) T(as_const_pointer(src)[i]); }
+        void assign(const void *src) { for(; i < n; ++i) array[i] = as_const_pointer(src)[i]; }
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+        void move_assign(const void *src)       { for(; i < n; ++i) array[i]         =  std::move(as_pointer(src)[i]);   }
+        void move_construct(const void *src)    { for(; i < n; ++i) new( &array[i] ) T( std::move(as_pointer(src)[i]) ); }
+#endif
+#if __TBB_MOVE_IF_NOEXCEPT_PRESENT
+        void move_construct_if_noexcept(const void *src)    { for(; i < n; ++i) new( &array[i] ) T( std::move_if_noexcept(as_pointer(src)[i]) ); }
+#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT
+
+        //TODO: rename to construct_range
         template<class I> void iterate(I &src) { for(; i < n; ++i, ++src) new( &array[i] ) T( *src ); }
         ~internal_loop_guide() {
-            if(i < n) // if exception raised, do zerroing on the rest of items
-                std::memset(array+i, 0, (n-i)*sizeof(value_type));
+            if(i < n) {// if an exception was raised, fill the rest of items with zeros
+                internal::handle_unconstructed_elements(array+i, n-i);
+            }
+        }
+    };
+
+    struct push_back_helper : internal::no_copy{
+        struct element_construction_guard : internal::no_copy{
+            pointer element;
+
+            element_construction_guard(pointer an_element) : element (an_element){}
+            void dismiss(){ element = NULL; }
+            ~element_construction_guard(){
+                if (element){
+                    internal::handle_unconstructed_elements(element, 1);
+                }
+            }
+        };
+
+        concurrent_vector & v;
+        size_type k;
+        element_construction_guard g;
+
+        push_back_helper(concurrent_vector & vector) :
+            v(vector),
+            g (static_cast<T*>(v.internal_push_back(sizeof(T),k)))
+        {}
+
+        pointer internal_push_back_result(){ return g.element;}
+        iterator return_iterator_and_dismiss(){
+            g.dismiss();
+            return iterator(v, k, g.element);
         }
     };
 };
 
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) 
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
 #pragma warning (push)
 #pragma warning (disable: 4701) // potentially uninitialized local variable "old"
 #endif
@@ -905,7 +1165,14 @@ template<typename T, class A>
 void concurrent_vector<T, A>::shrink_to_fit() {
     internal_segments_table old;
     __TBB_TRY {
-        if( internal_compact( sizeof(T), &old, &destroy_array, &copy_array ) )
+        internal_array_op2 copy_or_move_array =
+#if __TBB_MOVE_IF_NOEXCEPT_PRESENT
+                &move_array_if_noexcept
+#else
+                &copy_array
+#endif
+        ;
+        if( internal_compact( sizeof(T), &old, &destroy_array, copy_or_move_array ) )
             internal_free_segments( old.table, pointers_per_long_table, old.first_block ); // free joined and unnecessary segments
     } __TBB_CATCH(...) {
         if( old.first_block ) // free segment allocated for compacting. Only for support of exceptions in ctor of user T[ype]
@@ -913,39 +1180,43 @@ void concurrent_vector<T, A>::shrink_to_fit() {
         __TBB_RETHROW();
     }
 }
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) 
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
 #pragma warning (pop)
-#endif // warning 4701 is back 
+#endif // warning 4701 is back
 
 template<typename T, class A>
-void concurrent_vector<T, A>::internal_free_segments(void *table[], segment_index_t k, segment_index_t first_block) {
+void concurrent_vector<T, A>::internal_free_segments(segment_t table[], segment_index_t k, segment_index_t first_block) {
     // Free the arrays
     while( k > first_block ) {
         --k;
-        T* array = static_cast<T*>(table[k]);
-        table[k] = NULL;
-        if( array > internal::vector_allocation_error_flag ) // check for correct segment pointer
-            this->my_allocator.deallocate( array, segment_size(k) );
+        segment_value_t segment_value = table[k].load<relaxed>();
+        table[k].store<relaxed>(segment_not_used());
+        if( segment_value == segment_allocated() ) // check for correct segment pointer
+            this->my_allocator.deallocate( (segment_value.pointer<T>()), segment_size(k) );
     }
-    T* array = static_cast<T*>(table[0]);
-    if( array > internal::vector_allocation_error_flag ) {
+    segment_value_t segment_value = table[0].load<relaxed>();
+    if( segment_value == segment_allocated() ) {
         __TBB_ASSERT( first_block > 0, NULL );
-        while(k > 0) table[--k] = NULL;
-        this->my_allocator.deallocate( array, segment_size(first_block) );
+        while(k > 0) table[--k].store<relaxed>(segment_not_used());
+        this->my_allocator.deallocate( (segment_value.pointer<T>()), segment_size(first_block) );
     }
 }
 
 template<typename T, class A>
 T& concurrent_vector<T, A>::internal_subscript( size_type index ) const {
+    //TODO: unify both versions of internal_subscript
     __TBB_ASSERT( index < my_early_size, "index out of bounds" );
     size_type j = index;
     segment_index_t k = segment_base_index_of( j );
-    __TBB_ASSERT( (segment_t*)my_segment != my_storage || k < pointers_per_short_table, "index is being allocated" );
-    // no need in __TBB_load_with_acquire since thread works in own space or gets 
-    T* array = static_cast<T*>( tbb::internal::itt_hide_load_word(my_segment[k].array));
-    __TBB_ASSERT( array != internal::vector_allocation_error_flag, "the instance is broken by bad allocation. Use at() instead" );
-    __TBB_ASSERT( array, "index is being allocated" );
-    return array[j];
+    __TBB_ASSERT( my_segment.load<acquire>() != my_storage || k < pointers_per_short_table, "index is being allocated" );
+    //no need in load with acquire (load<acquire>) since thread works in own space or gets
+    //the information about added elements via some form of external synchronization
+    //TODO: why not make a load of my_segment relaxed as well ?
+    //TODO: add an assertion that my_segment[k] is properly aligned to please ITT
+    segment_value_t segment_value =  my_segment[k].template load<relaxed>();
+    __TBB_ASSERT( segment_value != segment_allocation_failed(), "the instance is broken by bad allocation. Use at() instead" );
+    __TBB_ASSERT( segment_value != segment_not_used(), "index is being allocated" );
+    return (( segment_value.pointer<T>()))[j];
 }
 
 template<typename T, class A>
@@ -954,12 +1225,17 @@ T& concurrent_vector<T, A>::internal_subscript_with_exceptions( size_type index
         internal::throw_exception(internal::eid_out_of_range); // throw std::out_of_range
     size_type j = index;
     segment_index_t k = segment_base_index_of( j );
-    if( (segment_t*)my_segment == my_storage && k >= pointers_per_short_table )
+    //TODO: refactor this condition into separate helper function, e.g. fits_into_small_table
+    if( my_segment.load<acquire>() == my_storage && k >= pointers_per_short_table )
         internal::throw_exception(internal::eid_segment_range_error); // throw std::range_error
-    void *array = my_segment[k].array; // no need in __TBB_load_with_acquire
-    if( array <= internal::vector_allocation_error_flag ) // check for correct segment pointer
+    // no need in load with acquire (load<acquire>) since thread works in own space or gets
+    //the information about added elements via some form of external synchronization
+    //TODO: why not make a load of my_segment relaxed as well ?
+    //TODO: add an assertion that my_segment[k] is properly aligned to please ITT
+    segment_value_t segment_value =  my_segment[k].template load<relaxed>();
+    if( segment_value != segment_allocated() ) // check for correct segment pointer
         internal::throw_exception(internal::eid_index_range_error); // throw std::range_error
-    return static_cast<T*>(array)[j];
+    return (segment_value.pointer<T>())[j];
 }
 
 template<typename T, class A> template<class I>
@@ -970,15 +1246,16 @@ void concurrent_vector<T, A>::internal_assign_iterators(I first, I last) {
     internal_reserve(n, sizeof(T), max_size());
     my_early_size = n;
     segment_index_t k = 0;
+    //TODO: unify segment iteration code with concurrent_base_v3::helper
     size_type sz = segment_size( my_first_block );
     while( sz < n ) {
-        internal_loop_guide loop(sz, my_segment[k].array);
+        internal_loop_guide loop(sz, my_segment[k].template load<relaxed>().template pointer<void>());
         loop.iterate(first);
         n -= sz;
         if( !k ) k = my_first_block;
         else { ++k; sz <<= 1; }
     }
-    internal_loop_guide loop(n, my_segment[k].array);
+    internal_loop_guide loop(n, my_segment[k].template load<relaxed>().template pointer<void>());
     loop.iterate(first);
 }
 
@@ -997,12 +1274,37 @@ void concurrent_vector<T, A>::copy_array( void* dst, const void* src, size_type
     internal_loop_guide loop(n, dst); loop.copy(src);
 }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+template<typename T, class A>
+void concurrent_vector<T, A>::move_array( void* dst, const void* src, size_type n ) {
+    internal_loop_guide loop(n, dst); loop.move_construct(src);
+}
+template<typename T, class A>
+void concurrent_vector<T, A>::move_assign_array( void* dst, const void* src, size_type n ) {
+    internal_loop_guide loop(n, dst); loop.move_assign(src);
+}
+#endif
+
+#if __TBB_MOVE_IF_NOEXCEPT_PRESENT
+template<typename T, class A>
+void concurrent_vector<T, A>::move_array_if_noexcept( void* dst, const void* src, size_type n ) {
+    internal_loop_guide loop(n, dst); loop.move_construct_if_noexcept(src);
+}
+#endif //__TBB_MOVE_IF_NOEXCEPT_PRESENT
+
+template<typename T, class A>
+template<typename I>
+void concurrent_vector<T, A>::copy_range( void* dst, const void* p_type_erased_iterator, size_type n ){
+    I & iterator ((*const_cast<I*>(static_cast<const I*>(p_type_erased_iterator))));
+    internal_loop_guide loop(n, dst); loop.iterate(iterator);
+}
+
 template<typename T, class A>
 void concurrent_vector<T, A>::assign_array( void* dst, const void* src, size_type n ) {
     internal_loop_guide loop(n, dst); loop.assign(src);
 }
 
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) 
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
     // Workaround for overzealous compiler warning
     #pragma warning (push)
     #pragma warning (disable: 4189)
@@ -1013,13 +1315,14 @@ void concurrent_vector<T, A>::destroy_array( void* begin, size_type n ) {
     for( size_type j=n; j>0; --j )
         array[j-1].~T(); // destructors are supposed to not throw any exceptions
 }
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) 
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
     #pragma warning (pop)
-#endif // warning 4189 is back 
+#endif // warning 4189 is back
 
 // concurrent_vector's template functions
 template<typename T, class A1, class A2>
 inline bool operator==(const concurrent_vector<T, A1> &a, const concurrent_vector<T, A2> &b) {
+    //TODO: call size() only once per vector (in operator==)
     // Simply:    return a.size() == b.size() && std::equal(a.begin(), a.end(), b.begin());
     if(a.size() != b.size()) return false;
     typename concurrent_vector<T, A1>::const_iterator i(a.begin());
@@ -1055,8 +1358,8 @@ inline void swap(concurrent_vector<T, A> &a, concurrent_vector<T, A> &b)
 
 } // namespace tbb
 
-#if defined(_MSC_VER) && !defined(__INTEL_COMPILER) && defined(_Wp64)
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
     #pragma warning (pop)
-#endif // warning 4267 is back
+#endif // warning 4267,4127 are back
 
 #endif /* __TBB_concurrent_vector_H */
index ea712d1f710956596d90810772998e3435a01080..b12cdcd8d10ffe7b1e9dec3c40b05df27478fc8c 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef _TBB_CRITICAL_SECTION_H_
@@ -58,7 +50,7 @@ public:
 
     critical_section_v4() { 
 #if _WIN32||_WIN64
-        InitializeCriticalSection(&my_impl);
+        InitializeCriticalSectionEx( &my_impl, 4000, 0 );
 #else
         pthread_mutex_init(&my_impl, NULL);
 #endif
index f0a2b57083fa51dd86465b7a23c4535988c9f57d..e121f8f4fdeedd5e5d03ac81ca00b4f50b6e4cac 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_enumerable_thread_specific_H
@@ -32,6 +24,7 @@
 #include "concurrent_vector.h"
 #include "tbb_thread.h"
 #include "tbb_allocator.h"
+#include "tbb_profiling.h"
 #include "cache_aligned_allocator.h"
 #include "aligned_space.h"
 #include <string.h>  // for memcpy
@@ -48,9 +41,11 @@ namespace tbb {
 enum ets_key_usage_type { ets_key_per_instance, ets_no_key };
 
 namespace interface6 {
+
     //! @cond
-    namespace internal { 
+    namespace internal {
+
+        using namespace tbb::internal;
 
         template<ets_key_usage_type ETS_key_type>
         class ets_base: tbb::internal::no_copy {
@@ -60,7 +55,7 @@ namespace interface6 {
 #else
             typedef pthread_t key_type;
 #endif
-#if __TBB_GCC_3_3_PROTECTED_BROKEN
+#if __TBB_PROTECTED_NESTED_CLASS_BROKEN
         public:
 #endif
             struct slot;
@@ -87,10 +82,10 @@ namespace interface6 {
                     return tbb::internal::punned_cast<tbb::atomic<key_type>*>(&key)->compare_and_swap(k,0)==0;
                 }
             };
-#if __TBB_GCC_3_3_PROTECTED_BROKEN
+#if __TBB_PROTECTED_NESTED_CLASS_BROKEN
         protected:
 #endif
-        
+
             static key_type key_of_current_thread() {
                tbb::tbb_thread::id id = tbb::this_tbb_thread::get_id();
                key_type k;
@@ -99,7 +94,7 @@ namespace interface6 {
             }
 
             //! Root of linked list of arrays of decreasing size.
-            /** NULL if and only if my_count==0.  
+            /** NULL if and only if my_count==0.
                 Each array in the list is half the size of its predecessor. */
             atomic<array*> my_root;
             atomic<size_t> my_count;
@@ -107,30 +102,28 @@ namespace interface6 {
             virtual void* create_array(size_t _size) = 0;  // _size in bytes
             virtual void free_array(void* ptr, size_t _size) = 0; // _size in bytes
             array* allocate( size_t lg_size ) {
-                size_t n = 1<<lg_size;  
+                size_t n = 1<<lg_size;
                 array* a = static_cast<array*>(create_array( sizeof(array)+n*sizeof(slot) ));
                 a->lg_size = lg_size;
                 std::memset( a+1, 0, n*sizeof(slot) );
                 return a;
             }
             void free(array* a) {
-                size_t n = 1<<(a->lg_size);  
+                size_t n = 1<<(a->lg_size);
                 free_array( (void *)a, size_t(sizeof(array)+n*sizeof(slot)) );
             }
             static size_t hash( key_type k ) {
                 // Multiplicative hashing.  Client should use *upper* bits.
                 // casts required for Mac gcc4.* compiler
-#if __TBB_WORDSIZE == 4
-                return uintptr_t(k)*0x9E3779B9;
-#else
-                return uintptr_t(k)*0x9E3779B97F4A7C15;
-#endif 
-            } 
-        
+                return uintptr_t(k)*tbb::internal::select_size_t_constant<0x9E3779B9,0x9E3779B97F4A7C15ULL>::value;
+            }
+
             ets_base() {my_root=NULL; my_count=0;}
             virtual ~ets_base();  // g++ complains if this is not virtual...
             void* table_lookup( bool& exists );
             void table_clear();
+            // table_find is used in copying ETS, so is not used in concurrent context.  So
+            // we don't need itt annotations for it.
             slot& table_find( key_type k ) {
                 size_t h = hash(k);
                 array* r = my_root;
@@ -166,15 +159,16 @@ namespace interface6 {
             }
             my_count = 0;
         }
-                
+
         template<ets_key_usage_type ETS_key_type>
         void* ets_base<ETS_key_type>::table_lookup( bool& exists ) {
-            const key_type k = key_of_current_thread(); 
+            const key_type k = key_of_current_thread();
 
             __TBB_ASSERT(k!=0,NULL);
             void* found;
             size_t h = hash(k);
             for( array* r=my_root; r; r=r->next ) {
+                call_itt_notify(acquired,r);
                 size_t mask=r->mask();
                 for(size_t i = r->start(h); ;i=(i+1)&mask) {
                     slot& s = r->at(i);
@@ -193,20 +187,25 @@ namespace interface6 {
                     }
                 }
             }
-            // Key does not yet exist
+            // Key does not yet exist.  The density of slots in the table does not exceed 0.5,
+            // for if this will occur a new table is allocated with double the current table
+            // size, which is swapped in as the new root table.  So an empty slot is guaranteed.
             exists = false;
             found = create_local();
             {
                 size_t c = ++my_count;
                 array* r = my_root;
+                call_itt_notify(acquired,r);
                 if( !r || c>r->size()/2 ) {
                     size_t s = r ? r->lg_size : 2;
                     while( c>size_t(1)<<(s-1) ) ++s;
                     array* a = allocate(s);
                     for(;;) {
-                        a->next = my_root;
+                        a->next = r;
+                        call_itt_notify(releasing,a);
                         array* new_r = my_root.compare_and_swap(a,r);
                         if( new_r==r ) break;
+                        call_itt_notify(acquired, new_r);
                         if( new_r->lg_size>=s ) {
                             // Another thread inserted an equal or  bigger array, so our array is superfluous.
                             free(a);
@@ -217,8 +216,11 @@ namespace interface6 {
                 }
             }
         insert:
-            // Guaranteed to be room for it, and it is not present, so search for empty slot and grab it.
+        // Whether a slot has been found in an older table, or if it has been inserted at this level,
+        // it has already been accounted for in the total.  Guaranteed to be room for it, and it is
+        // not present, so search for empty slot and use it.
             array* ir = my_root;
+            call_itt_notify(acquired, ir);
             size_t mask = ir->mask();
             for(size_t i = ir->start(h);;i=(i+1)&mask) {
                 slot& s = ir->at(i);
@@ -231,16 +233,24 @@ namespace interface6 {
             }
         }
 
-        //! Specialization that exploits native TLS 
+        //! Specialization that exploits native TLS
         template <>
         class ets_base<ets_key_per_instance>: protected ets_base<ets_no_key> {
             typedef ets_base<ets_no_key> super;
 #if _WIN32||_WIN64
+#if __TBB_WIN8UI_SUPPORT
+            typedef DWORD tls_key_t;
+            void create_key() { my_key = FlsAlloc(NULL); }
+            void destroy_key() { FlsFree(my_key); }
+            void set_tls(void * value) { FlsSetValue(my_key, (LPVOID)value); }
+            void* get_tls() { return (void *)FlsGetValue(my_key); }
+#else
             typedef DWORD tls_key_t;
             void create_key() { my_key = TlsAlloc(); }
             void destroy_key() { TlsFree(my_key); }
             void set_tls(void * value) { TlsSetValue(my_key, (LPVOID)value); }
             void* get_tls() { return (void *)TlsGetValue(my_key); }
+#endif
 #else
             typedef pthread_key_t tls_key_t;
             void create_key() { pthread_key_create(&my_key, NULL); }
@@ -263,79 +273,79 @@ namespace interface6 {
                     found = super::table_lookup(exists);
                     set_tls(found);
                 }
-                return found; 
+                return found;
             }
             void table_clear() {
                 destroy_key();
-                create_key(); 
+                create_key();
                 super::table_clear();
             }
         };
 
         //! Random access iterator for traversing the thread local copies.
         template< typename Container, typename Value >
-        class enumerable_thread_specific_iterator 
-#if defined(_WIN64) && defined(_MSC_VER) 
+        class enumerable_thread_specific_iterator
+#if defined(_WIN64) && defined(_MSC_VER)
             // Ensure that Microsoft's internal template function _Val_type works correctly.
             : public std::iterator<std::random_access_iterator_tag,Value>
 #endif /* defined(_WIN64) && defined(_MSC_VER) */
         {
-            //! current position in the concurrent_vector 
-        
+            //! current position in the concurrent_vector
+
             Container *my_container;
             typename Container::size_type my_index;
             mutable Value *my_value;
-        
+
             template<typename C, typename T>
-            friend enumerable_thread_specific_iterator<C,T> operator+( ptrdiff_t offset, 
+            friend enumerable_thread_specific_iterator<C,T> operator+( ptrdiff_t offset,
                                                                        const enumerable_thread_specific_iterator<C,T>& v );
-        
+
             template<typename C, typename T, typename U>
-            friend bool operator==( const enumerable_thread_specific_iterator<C,T>& i, 
+            friend bool operator==( const enumerable_thread_specific_iterator<C,T>& i,
                                     const enumerable_thread_specific_iterator<C,U>& j );
-        
+
             template<typename C, typename T, typename U>
-            friend bool operator<( const enumerable_thread_specific_iterator<C,T>& i, 
+            friend bool operator<( const enumerable_thread_specific_iterator<C,T>& i,
                                    const enumerable_thread_specific_iterator<C,U>& j );
-        
+
             template<typename C, typename T, typename U>
             friend ptrdiff_t operator-( const enumerable_thread_specific_iterator<C,T>& i, const enumerable_thread_specific_iterator<C,U>& j );
-            
-            template<typename C, typename U> 
+
+            template<typename C, typename U>
             friend class enumerable_thread_specific_iterator;
-        
+
             public:
-        
-            enumerable_thread_specific_iterator( const Container &container, typename Container::size_type index ) : 
+
+            enumerable_thread_specific_iterator( const Container &container, typename Container::size_type index ) :
                 my_container(&const_cast<Container &>(container)), my_index(index), my_value(NULL) {}
-        
+
             //! Default constructor
             enumerable_thread_specific_iterator() : my_container(NULL), my_index(0), my_value(NULL) {}
-        
+
             template<typename U>
             enumerable_thread_specific_iterator( const enumerable_thread_specific_iterator<Container, U>& other ) :
                     my_container( other.my_container ), my_index( other.my_index), my_value( const_cast<Value *>(other.my_value) ) {}
-        
+
             enumerable_thread_specific_iterator operator+( ptrdiff_t offset ) const {
                 return enumerable_thread_specific_iterator(*my_container, my_index + offset);
             }
-        
+
             enumerable_thread_specific_iterator &operator+=( ptrdiff_t offset ) {
                 my_index += offset;
                 my_value = NULL;
                 return *this;
             }
-        
+
             enumerable_thread_specific_iterator operator-( ptrdiff_t offset ) const {
                 return enumerable_thread_specific_iterator( *my_container, my_index-offset );
             }
-        
+
             enumerable_thread_specific_iterator &operator-=( ptrdiff_t offset ) {
                 my_index -= offset;
                 my_value = NULL;
                 return *this;
             }
-        
+
             Value& operator*() const {
                 Value* value = my_value;
                 if( !value ) {
@@ -344,25 +354,25 @@ namespace interface6 {
                 __TBB_ASSERT( value==reinterpret_cast<Value *>(&(*my_container)[my_index].value), "corrupt cache" );
                 return *value;
             }
-        
+
             Value& operator[]( ptrdiff_t k ) const {
                return (*my_container)[my_index + k].value;
             }
-        
+
             Value* operator->() const {return &operator*();}
-        
+
             enumerable_thread_specific_iterator& operator++() {
                 ++my_index;
                 my_value = NULL;
                 return *this;
             }
-        
+
             enumerable_thread_specific_iterator& operator--() {
                 --my_index;
                 my_value = NULL;
                 return *this;
             }
-        
+
             //! Post increment
             enumerable_thread_specific_iterator operator++(int) {
                 enumerable_thread_specific_iterator result = *this;
@@ -370,7 +380,7 @@ namespace interface6 {
                 my_value = NULL;
                 return result;
             }
-        
+
             //! Post decrement
             enumerable_thread_specific_iterator operator--(int) {
                 enumerable_thread_specific_iterator result = *this;
@@ -378,7 +388,7 @@ namespace interface6 {
                 my_value = NULL;
                 return result;
             }
-        
+
             // STL support
             typedef ptrdiff_t difference_type;
             typedef Value value_type;
@@ -386,51 +396,51 @@ namespace interface6 {
             typedef Value& reference;
             typedef std::random_access_iterator_tag iterator_category;
         };
-        
+
         template<typename Container, typename T>
-        enumerable_thread_specific_iterator<Container,T> operator+( ptrdiff_t offset, 
+        enumerable_thread_specific_iterator<Container,T> operator+( ptrdiff_t offset,
                                                                     const enumerable_thread_specific_iterator<Container,T>& v ) {
             return enumerable_thread_specific_iterator<Container,T>( v.my_container, v.my_index + offset );
         }
-        
+
         template<typename Container, typename T, typename U>
-        bool operator==( const enumerable_thread_specific_iterator<Container,T>& i, 
+        bool operator==( const enumerable_thread_specific_iterator<Container,T>& i,
                          const enumerable_thread_specific_iterator<Container,U>& j ) {
             return i.my_index==j.my_index && i.my_container == j.my_container;
         }
-        
+
         template<typename Container, typename T, typename U>
-        bool operator!=( const enumerable_thread_specific_iterator<Container,T>& i, 
+        bool operator!=( const enumerable_thread_specific_iterator<Container,T>& i,
                          const enumerable_thread_specific_iterator<Container,U>& j ) {
             return !(i==j);
         }
-        
+
         template<typename Container, typename T, typename U>
-        bool operator<( const enumerable_thread_specific_iterator<Container,T>& i, 
+        bool operator<( const enumerable_thread_specific_iterator<Container,T>& i,
                         const enumerable_thread_specific_iterator<Container,U>& j ) {
             return i.my_index<j.my_index;
         }
-        
+
         template<typename Container, typename T, typename U>
-        bool operator>( const enumerable_thread_specific_iterator<Container,T>& i, 
+        bool operator>( const enumerable_thread_specific_iterator<Container,T>& i,
                         const enumerable_thread_specific_iterator<Container,U>& j ) {
             return j<i;
         }
-        
+
         template<typename Container, typename T, typename U>
-        bool operator>=( const enumerable_thread_specific_iterator<Container,T>& i, 
+        bool operator>=( const enumerable_thread_specific_iterator<Container,T>& i,
                          const enumerable_thread_specific_iterator<Container,U>& j ) {
             return !(i<j);
         }
-        
+
         template<typename Container, typename T, typename U>
-        bool operator<=( const enumerable_thread_specific_iterator<Container,T>& i, 
+        bool operator<=( const enumerable_thread_specific_iterator<Container,T>& i,
                          const enumerable_thread_specific_iterator<Container,U>& j ) {
             return !(j<i);
         }
-        
+
         template<typename Container, typename T, typename U>
-        ptrdiff_t operator-( const enumerable_thread_specific_iterator<Container,T>& i, 
+        ptrdiff_t operator-( const enumerable_thread_specific_iterator<Container,T>& i,
                              const enumerable_thread_specific_iterator<Container,U>& j ) {
             return i.my_index-j.my_index;
         }
@@ -446,15 +456,15 @@ namespace interface6 {
 
             template<typename C, typename T, typename U>
             friend bool operator!=(const segmented_iterator<C,T>& i, const segmented_iterator<C,U>& j);
-            
-            template<typename C, typename U> 
+
+            template<typename C, typename U>
             friend class segmented_iterator;
 
             public:
 
                 segmented_iterator() {my_segcont = NULL;}
 
-                segmented_iterator( const SegmentedContainer& _segmented_container ) : 
+                segmented_iterator( const SegmentedContainer& _segmented_container ) :
                     my_segcont(const_cast<SegmentedContainer*>(&_segmented_container)),
                     outer_iter(my_segcont->end()) { }
 
@@ -559,7 +569,7 @@ namespace interface6 {
         };    // segmented_iterator
 
         template<typename SegmentedContainer, typename T, typename U>
-        bool operator==( const segmented_iterator<SegmentedContainer,T>& i, 
+        bool operator==( const segmented_iterator<SegmentedContainer,T>& i,
                          const segmented_iterator<SegmentedContainer,U>& j ) {
             if(i.my_segcont != j.my_segcont) return false;
             if(i.my_segcont == NULL) return true;
@@ -570,14 +580,14 @@ namespace interface6 {
 
         // !=
         template<typename SegmentedContainer, typename T, typename U>
-        bool operator!=( const segmented_iterator<SegmentedContainer,T>& i, 
+        bool operator!=( const segmented_iterator<SegmentedContainer,T>& i,
                          const segmented_iterator<SegmentedContainer,U>& j ) {
             return !(i==j);
         }
 
         template<typename T>
         struct destruct_only: tbb::internal::no_copy {
-            tbb::aligned_space<T,1> value;
+            tbb::aligned_space<T> value;
             ~destruct_only() {value.begin()[0].~T();}
         };
 
@@ -622,8 +632,7 @@ namespace interface6 {
             typedef typename tbb::tbb_allocator<callback_leaf> my_allocator_type;
 
             /*override*/ callback_base<T>* clone() {
-                void* where = my_allocator_type().allocate(1);
-                return new(where) callback_leaf(*this);
+                return make(*this);
             }
 
             /*override*/ void destroy() {
@@ -633,7 +642,7 @@ namespace interface6 {
 
             /*override*/ void construct(void* where) {
                 Constructor::construct(where);
-            }  
+            }
         public:
             template<typename X>
             static callback_base<T>* make( const X& x ) {
@@ -650,6 +659,7 @@ namespace interface6 {
         */
         template<typename U, size_t ModularSize>
         struct ets_element {
+            ets_element() { /* avoid cl warning C4345 about default initialization of POD types */ }
             char value[ModularSize==0 ? sizeof(U) : sizeof(U)+(tbb::internal::NFS_MaxLineSize-ModularSize)];
             void unconstruct() {
                 tbb::internal::punned_cast<U*>(&value)->~U();
@@ -667,25 +677,25 @@ namespace interface6 {
         - enumerable_thread_specific containers may be copy-constructed or assigned.
         - thread-local copies can be managed by hash-table, or can be accessed via TLS storage for speed.
         - outside of parallel contexts, the contents of all thread-local copies are accessible by iterator or using combine or combine_each methods
-        
+
     @par Segmented iterator
         When the thread-local objects are containers with input_iterators defined, a segmented iterator may
         be used to iterate over all the elements of all thread-local copies.
 
     @par combine and combine_each
-        - Both methods are defined for enumerable_thread_specific. 
-        - combine() requires the the type T have operator=() defined.  
-        - neither method modifies the contents of the object (though there is no guarantee that the applied methods do not modify the object.)  
+        - Both methods are defined for enumerable_thread_specific.
+        - combine() requires the the type T have operator=() defined.
+        - neither method modifies the contents of the object (though there is no guarantee that the applied methods do not modify the object.)
         - Both are evaluated in serial context (the methods are assumed to be non-benign.)
-        
+
     @ingroup containers */
-    template <typename T, 
-              typename Allocator=cache_aligned_allocator<T>, 
-              ets_key_usage_type ETS_key_type=ets_no_key > 
-    class enumerable_thread_specific: internal::ets_base<ETS_key_type> { 
+    template <typename T,
+              typename Allocator=cache_aligned_allocator<T>,
+              ets_key_usage_type ETS_key_type=ets_no_key >
+    class enumerable_thread_specific: internal::ets_base<ETS_key_type> {
 
         template<typename U, typename A, ets_key_usage_type C> friend class enumerable_thread_specific;
-    
+
         typedef internal::ets_element<T,sizeof(T)%tbb::internal::NFS_MaxLineSize> padded_element;
 
         //! A generic range, used to create range objects from the iterators
@@ -697,28 +707,24 @@ namespace interface6 {
             typedef const T& const_reference;
             typedef I iterator;
             typedef ptrdiff_t difference_type;
-            generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range<I>(begin_,end_,grainsize_) {} 
+            generic_range_type( I begin_, I end_, size_t grainsize_ = 1) : blocked_range<I>(begin_,end_,grainsize_) {}
             template<typename U>
-            generic_range_type( const generic_range_type<U>& r) : blocked_range<I>(r.begin(),r.end(),r.grainsize()) {} 
+            generic_range_type( const generic_range_type<U>& r) : blocked_range<I>(r.begin(),r.end(),r.grainsize()) {}
             generic_range_type( generic_range_type& r, split ) : blocked_range<I>(r,split()) {}
         };
-    
+
         typedef typename Allocator::template rebind< padded_element >::other padded_allocator_type;
         typedef tbb::concurrent_vector< padded_element, padded_allocator_type > internal_collection_type;
-        
+
         internal::callback_base<T> *my_construct_callback;
 
         internal_collection_type my_locals;
-   
+
         /*override*/ void* create_local() {
-#if TBB_DEPRECATED
-            void* lref = &my_locals[my_locals.push_back(padded_element())];
-#else
-            void* lref = &*my_locals.push_back(padded_element());
-#endif
+            void* lref = &*my_locals.grow_by(1);
             my_construct_callback->construct(lref);
             return lref;
-        } 
+        }
 
         void unconstruct_locals() {
             for(typename internal_collection_type::iterator cvi = my_locals.begin(); cvi != my_locals.end(); ++cvi) {
@@ -738,9 +744,9 @@ namespace interface6 {
             size_t nelements = (_size + sizeof(uintptr_t) -1) / sizeof(uintptr_t);
             array_allocator_type().deallocate( reinterpret_cast<uintptr_t *>(_ptr),nelements);
         }
-   
+
     public:
-    
+
         //! Basic types
         typedef Allocator allocator_type;
         typedef T value_type;
@@ -750,7 +756,7 @@ namespace interface6 {
         typedef const T* const_pointer;
         typedef typename internal_collection_type::size_type size_type;
         typedef typename internal_collection_type::difference_type difference_type;
-    
+
         // Iterator types
         typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, value_type > iterator;
         typedef typename internal::enumerable_thread_specific_iterator< internal_collection_type, const value_type > const_iterator;
@@ -758,30 +764,30 @@ namespace interface6 {
         // Parallel range types
         typedef generic_range_type< iterator > range_type;
         typedef generic_range_type< const_iterator > const_range_type;
-    
+
         //! Default constructor.  Each local instance of T is default constructed.
-        enumerable_thread_specific() : 
-            my_construct_callback( internal::callback_leaf<T,internal::construct_by_default<T> >::make(/*dummy argument*/0) ) 
-        {}
+        enumerable_thread_specific() : my_construct_callback(
+            internal::callback_leaf<T,internal::construct_by_default<T> >::make(/*dummy argument*/0)
+        ){}
 
         //! Constructor with initializer functor.  Each local instance of T is constructed by T(finit()).
         template <typename Finit>
-        enumerable_thread_specific( Finit finit ) : 
-            my_construct_callback( internal::callback_leaf<T,internal::construct_by_finit<T,Finit> >::make( finit ) ) 
-        {}
-    
-        //! Constuctor with exemplar.  Each local instance of T is copied-constructed from the exemplar.
-        enumerable_thread_specific(const T& exemplar) : 
-            my_construct_callback( internal::callback_leaf<T,internal::construct_by_exemplar<T> >::make( exemplar ) )
-        {}
-    
+        enumerable_thread_specific( Finit finit ) : my_construct_callback(
+            internal::callback_leaf<T,internal::construct_by_finit<T,Finit> >::make( finit )
+        ){}
+
+        //! Constructor with exemplar. Each local instance of T is copy-constructed from the exemplar.
+        enumerable_thread_specific( const T& exemplar ) : my_construct_callback(
+            internal::callback_leaf<T,internal::construct_by_exemplar<T> >::make( exemplar )
+        ){}
+
         //! Destructor
-        ~enumerable_thread_specific() { 
+        ~enumerable_thread_specific() {
             my_construct_callback->destroy();
             this->clear();  // deallocation before the derived class is finished destructing
             // So free(array *) is still accessible
         }
-      
+
         //! returns reference to local, discarding exists
         reference local() {
             bool exists;
@@ -796,24 +802,24 @@ namespace interface6 {
 
         //! Get the number of local copies
         size_type size() const { return my_locals.size(); }
-    
+
         //! true if there have been no local copies created
         bool empty() const { return my_locals.empty(); }
-    
+
         //! begin iterator
         iterator begin() { return iterator( my_locals, 0 ); }
         //! end iterator
         iterator end() { return iterator(my_locals, my_locals.size() ); }
-    
+
         //! begin const iterator
         const_iterator begin() const { return const_iterator(my_locals, 0); }
-    
+
         //! end const iterator
         const_iterator end() const { return const_iterator(my_locals, my_locals.size()); }
 
         //! Get range for parallel algorithms
-        range_type range( size_t grainsize=1 ) { return range_type( begin(), end(), grainsize ); } 
-        
+        range_type range( size_t grainsize=1 ) { return range_type( begin(), end(), grainsize ); }
+
         //! Get const range for parallel algorithms
         const_range_type range( size_t grainsize=1 ) const { return const_range_type( begin(), end(), grainsize ); }
 
@@ -828,13 +834,13 @@ namespace interface6 {
 
     private:
 
-        template<typename U, typename A2, ets_key_usage_type C2>
-        void internal_copy( const enumerable_thread_specific<U, A2, C2>& other);
+        template<typename A2, ets_key_usage_type C2>
+        void internal_copy( const enumerable_thread_specific<T, A2, C2>& other);
 
     public:
 
-        template<typename U, typename Alloc, ets_key_usage_type Cachetype>
-        enumerable_thread_specific( const enumerable_thread_specific<U, Alloc, Cachetype>& other ) : internal::ets_base<ETS_key_type> ()
+        template<typename Alloc, ets_key_usage_type Cachetype>
+        enumerable_thread_specific( const enumerable_thread_specific<T, Alloc, Cachetype>& other ) : internal::ets_base<ETS_key_type> ()
         {
             internal_copy(other);
         }
@@ -846,11 +852,11 @@ namespace interface6 {
 
     private:
 
-        template<typename U, typename A2, ets_key_usage_type C2>
+        template<typename A2, ets_key_usage_type C2>
         enumerable_thread_specific &
-        internal_assign(const enumerable_thread_specific<U, A2, C2>& other) {
+        internal_assign(const enumerable_thread_specific<T, A2, C2>& other) {
             if(static_cast<void *>( this ) != static_cast<const void *>( &other )) {
-                this->clear(); 
+                this->clear();
                 my_construct_callback->destroy();
                 my_construct_callback = 0;
                 internal_copy( other );
@@ -865,8 +871,8 @@ namespace interface6 {
             return internal_assign(other);
         }
 
-        template<typename U, typename Alloc, ets_key_usage_type Cachetype>
-        enumerable_thread_specific& operator=(const enumerable_thread_specific<U, Alloc, Cachetype>& other)
+        template<typename Alloc, ets_key_usage_type Cachetype>
+        enumerable_thread_specific& operator=(const enumerable_thread_specific<T, Alloc, Cachetype>& other)
         {
             return internal_assign(other);
         }
@@ -881,7 +887,7 @@ namespace interface6 {
             }
             const_iterator ci = begin();
             T my_result = *ci;
-            while(++ci != end()) 
+            while(++ci != end())
                 my_result = f_combine( my_result, *ci );
             return my_result;
         }
@@ -896,9 +902,9 @@ namespace interface6 {
 
     }; // enumerable_thread_specific
 
-    template <typename T, typename Allocator, ets_key_usage_type ETS_key_type> 
-    template<typename U, typename A2, ets_key_usage_type C2>
-    void enumerable_thread_specific<T,Allocator,ETS_key_type>::internal_copy( const enumerable_thread_specific<U, A2, C2>& other) {
+    template <typename T, typename Allocator, ets_key_usage_type ETS_key_type>
+    template<typename A2, ets_key_usage_type C2>
+    void enumerable_thread_specific<T,Allocator,ETS_key_type>::internal_copy( const enumerable_thread_specific<T, A2, C2>& other) {
         // Initialize my_construct_callback first, so that it is valid even if rest of this routine throws an exception.
         my_construct_callback = other.my_construct_callback->clone();
 
@@ -910,17 +916,13 @@ namespace interface6 {
                 base::slot& s1 = r->at(i);
                 if( !s1.empty() ) {
                     base::slot& s2 = this->table_find(s1.key);
-                    if( s2.empty() ) { 
-#if TBB_DEPRECATED
-                        void* lref = &my_locals[my_locals.push_back(padded_element())];
-#else
-                        void* lref = &*my_locals.push_back(padded_element());
-#endif
-                        s2.ptr = new(lref) T(*(U*)s1.ptr);
+                    if( s2.empty() ) {
+                        void* lref = &*my_locals.grow_by(1);
+                        s2.ptr = new(lref) T(*(T*)s1.ptr);
                         s2.key = s1.key;
                     } else {
                         // Skip the duplicate
-                    } 
+                    }
                 }
             }
         }
@@ -947,10 +949,10 @@ namespace interface6 {
         typedef typename internal::segmented_iterator<Container, value_type> iterator;
         typedef typename internal::segmented_iterator<Container, const value_type> const_iterator;
 
-        flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) : 
+        flattened2d( const Container &c, typename Container::const_iterator b, typename Container::const_iterator e ) :
             my_container(const_cast<Container*>(&c)), my_begin(b), my_end(e) { }
 
-        flattened2d( const Container &c ) : 
+        flattened2d( const Container &c ) :
             my_container(const_cast<Container*>(&c)), my_begin(c.begin()), my_end(c.end()) { }
 
         iterator begin() { return iterator(*my_container) = my_begin; }
index 98da0f5b6aa3d710a6ee34b560266764d2cbe3b4..68626e8a03fdb6562a71330fe20e1a5a7ab10035 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_flow_graph_H
 #include "spin_rw_mutex.h"
 #include "null_rw_mutex.h"
 #include "task.h"
-#include "concurrent_vector.h"
+#include "cache_aligned_allocator.h"
+#include "tbb_exception.h"
 #include "internal/_aggregator_impl.h"
+#include "tbb_profiling.h"
+
+#if TBB_DEPRECATED_FLOW_ENQUEUE
+#define FLOW_SPAWN(a) tbb::task::enqueue((a))
+#else
+#define FLOW_SPAWN(a) tbb::task::spawn((a))
+#endif
 
 // use the VC10 or gcc version of tuple if it is available.
-#if TBB_IMPLEMENT_CPP0X && (!defined(_MSC_VER) || _MSC_VER < 1600)
-#define TBB_PREVIEW_TUPLE 1
-#include "compat/tuple"
+#if __TBB_CPP11_TUPLE_PRESENT
+    #include <tuple>
+namespace tbb {
+    namespace flow {
+        using std::tuple;
+        using std::tuple_size;
+        using std::tuple_element;
+        using std::get;
+    }
+}
 #else
-#include <tuple>
+    #include "compat/tuple"
 #endif
 
 #include<list>
@@ -57,7 +64,7 @@
   passed between nodes in a graph.  These messages may contain data or
   simply act as signals that a predecessors has completed. The graph
   class and its associated node classes can be used to express such
-  applcations.
+  applications.
 */
 
 namespace tbb {
@@ -66,112 +73,223 @@ namespace flow {
 //! An enumeration the provides the two most common concurrency levels: unlimited and serial
 enum concurrency { unlimited = 0, serial = 1 };
 
-namespace interface6 {
+namespace interface7 {
 
-//! The base of all graph nodes.  Allows them to be stored in a collection for deletion.
-class graph_node {
-public:
-    virtual ~graph_node() {} 
-}
+namespace internal {
+    template<typename T, typename M> class successor_cache;
+    template<typename T, typename M> class broadcast_cache;
+    template<typename T, typename M> class round_robin_cache;
+}
 
-//! An empty class used for messages that mean "I'm done" 
+//! An empty class used for messages that mean "I'm done"
 class continue_msg {};
-        
+
 template< typename T > class sender;
 template< typename T > class receiver;
 class continue_receiver;
-        
+
 //! Pure virtual template class that defines a sender of messages of type T
 template< typename T >
 class sender {
 public:
     //! The output type of this sender
     typedef T output_type;
-        
+
     //! The successor type for this node
     typedef receiver<T> successor_type;
-        
+
     virtual ~sender() {}
-        
+
     //! Add a new successor to this node
     virtual bool register_successor( successor_type &r ) = 0;
-        
+
     //! Removes a successor from this node
     virtual bool remove_successor( successor_type &r ) = 0;
-        
+
     //! Request an item from the sender
     virtual bool try_get( T & ) { return false; }
-        
-    //! Reserves an item in the sender 
+
+    //! Reserves an item in the sender
     virtual bool try_reserve( T & ) { return false; }
-        
+
     //! Releases the reserved item
     virtual bool try_release( ) { return false; }
-        
+
     //! Consumes the reserved item
     virtual bool try_consume( ) { return false; }
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    //! interface to record edges for traversal & deletion
+    virtual void    internal_add_built_successor( successor_type & )    = 0;
+    virtual void    internal_delete_built_successor( successor_type & ) = 0;
+    virtual void    copy_successors( std::vector<successor_type *> &)   = 0;
+    virtual size_t  successor_count()                                   = 0;
+#endif
+};
+
+template< typename T > class limiter_node;  // needed for resetting decrementer
+template< typename R, typename B > class run_and_put_task;
+
+static tbb::task * const SUCCESSFULLY_ENQUEUED = (task *)-1;
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+// flags to modify the behavior of the graph reset().  Can be combined.
+enum reset_flags {
+    rf_reset_protocol   = 0,
+    rf_reset_bodies     = 1<<0,  // delete the current node body, reset to a copy of the initial node body.
+    rf_extract          = 1<<1   // delete edges (extract() for single node, reset() for graph.)
 };
-        
-        
+
+#define __TBB_PFG_RESET_ARG(exp) exp
+#define __TBB_COMMA ,
+#else
+#define __TBB_PFG_RESET_ARG(exp)  /* nothing */
+#define __TBB_COMMA /* nothing */
+#endif
+
+// enqueue left task if necessary.  Returns the non-enqueued task if there is one.
+static inline tbb::task *combine_tasks( tbb::task * left, tbb::task * right) {
+    // if no RHS task, don't change left.
+    if(right == NULL) return left;
+    // right != NULL
+    if(left == NULL) return right;
+    if(left == SUCCESSFULLY_ENQUEUED) return right;
+    // left contains a task
+    if(right != SUCCESSFULLY_ENQUEUED) {
+        // both are valid tasks
+        FLOW_SPAWN(*left);
+        return right;
+    }
+    return left;
+}
+
 //! Pure virtual template class that defines a receiver of messages of type T
 template< typename T >
 class receiver {
 public:
-        
     //! The input type of this receiver
     typedef T input_type;
-        
+
     //! The predecessor type for this node
     typedef sender<T> predecessor_type;
-        
+
     //! Destructor
     virtual ~receiver() {}
-        
+
     //! Put an item to the receiver
-    virtual bool try_put( const T& t ) = 0;
-        
+    bool try_put( const T& t ) {
+        task *res = try_put_task(t);
+        if(!res) return false;
+        if (res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res);
+        return true;
+    }
+
+    //! put item to successor; return task to run the successor if possible.
+protected:
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    virtual task *try_put_task(const T& t) = 0;
+public:
+
     //! Add a predecessor to the node
     virtual bool register_predecessor( predecessor_type & ) { return false; }
-        
+
     //! Remove a predecessor from the node
     virtual bool remove_predecessor( predecessor_type & ) { return false; }
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    virtual void   internal_add_built_predecessor( predecessor_type & )    = 0;
+    virtual void   internal_delete_built_predecessor( predecessor_type & ) = 0;
+    virtual void   copy_predecessors( std::vector<predecessor_type *> & )  = 0;
+    virtual size_t predecessor_count()                                     = 0;
+#endif
+
+protected:
+    //! put receiver back in initial state
+    template<typename U> friend class limiter_node;
+    virtual void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f = rf_reset_protocol ) ) = 0;
+
+    template<typename TT, typename M>
+        friend class internal::successor_cache;
+    virtual bool is_continue_receiver() { return false; }
+};
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+//* holder of edges both for caches and for those nodes which do not have predecessor caches.
+// C == receiver< ... > or sender< ... >, depending.
+template<typename C>
+class edge_container {
+
+public:
+    typedef std::vector<C *> edge_vector;
+
+    void add_edge( C &s) {
+        built_edges.push_back( &s );
+    }
+
+    void delete_edge( C &s) {
+        for ( typename edge_vector::iterator i = built_edges.begin(); i != built_edges.end(); ++i ) {
+            if ( *i == &s )  {
+                (void)built_edges.erase(i);
+                return;  // only remove one predecessor per request
+            }
+        }
+    }
+
+    void copy_edges( edge_vector &v) {
+        v = built_edges;
+    }
+
+    size_t edge_count() {
+        return (size_t)(built_edges.size());
+    }
+
+    void clear() {
+        built_edges.clear();
+    }
+
+    template< typename S > void sender_extract( S &s ); 
+    template< typename R > void receiver_extract( R &r ); 
+    
+private: 
+    edge_vector built_edges;
 };
-        
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
 //! Base class for receivers of completion messages
 /** These receivers automatically reset, but cannot be explicitly waited on */
 class continue_receiver : public receiver< continue_msg > {
 public:
-        
+
     //! The input type
     typedef continue_msg input_type;
-        
+
     //! The predecessor type for this node
     typedef sender< continue_msg > predecessor_type;
-        
+
     //! Constructor
-    continue_receiver( int number_of_predecessors = 0 ) { 
+    continue_receiver( int number_of_predecessors = 0 ) {
         my_predecessor_count = my_initial_predecessor_count = number_of_predecessors;
         my_current_count = 0;
     }
-        
+
     //! Copy constructor
-    continue_receiver( const continue_receiver& src ) : receiver<continue_msg>() { 
+    continue_receiver( const continue_receiver& src ) : receiver<continue_msg>() {
         my_predecessor_count = my_initial_predecessor_count = src.my_initial_predecessor_count;
         my_current_count = 0;
     }
-        
+
     //! Destructor
     virtual ~continue_receiver() { }
-        
+
     //! Increments the trigger threshold
     /* override */ bool register_predecessor( predecessor_type & ) {
         spin_mutex::scoped_lock l(my_mutex);
         ++my_predecessor_count;
         return true;
     }
-        
+
     //! Decrements the trigger threshold
     /** Does not check to see if the removal of the predecessor now makes the current count
         exceed the new threshold.  So removing a predecessor while the graph is active can cause
@@ -181,46 +299,170 @@ public:
         --my_predecessor_count;
         return true;
     }
-        
-    //! Puts a continue_msg to the receiver
-    /** If the message causes the message count to reach the predecessor count, execute() is called and
-        the message count is reset to 0.  Otherwise the message count is incremented. */
-    /* override */ bool try_put( const input_type & ) {
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    typedef std::vector<predecessor_type *> predecessor_vector_type;
+
+    /*override*/ void internal_add_built_predecessor( predecessor_type &s) {
+        spin_mutex::scoped_lock l(my_mutex);
+        my_built_predecessors.add_edge( s );
+    }
+
+    /*override*/ void internal_delete_built_predecessor( predecessor_type &s) {
+        spin_mutex::scoped_lock l(my_mutex);
+        my_built_predecessors.delete_edge(s);
+    }
+
+    /*override*/ void copy_predecessors( predecessor_vector_type &v) {
+        spin_mutex::scoped_lock l(my_mutex);
+        my_built_predecessors.copy_edges(v);
+    }
+
+    /*override*/ size_t predecessor_count() {
+        spin_mutex::scoped_lock l(my_mutex);
+        return my_built_predecessors.edge_count();
+    }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+    
+protected:
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    // execute body is supposed to be too small to create a task for.
+    /* override */ task *try_put_task( const input_type & ) {
         {
             spin_mutex::scoped_lock l(my_mutex);
-            if ( ++my_current_count < my_predecessor_count ) 
-                return true;
+            if ( ++my_current_count < my_predecessor_count )
+                return SUCCESSFULLY_ENQUEUED;
             else
                 my_current_count = 0;
         }
-        execute();
-        return true;
+        task * res = execute();
+        if(!res) return SUCCESSFULLY_ENQUEUED;
+        return res;
     }
-        
-protected:
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    edge_container<predecessor_type> my_built_predecessors;
+#endif
     spin_mutex my_mutex;
     int my_predecessor_count;
     int my_current_count;
     int my_initial_predecessor_count;
-        
+    // the friend declaration in the base class did not eliminate the "protected class"
+    // error in gcc 4.1.2
+    template<typename U> friend class limiter_node;
+    /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f) )
+    {
+        my_current_count = 0;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        if(f & rf_extract) {
+            my_built_predecessors.receiver_extract(*this);
+            my_predecessor_count = my_initial_predecessor_count;
+        }
+#endif
+    }
+
     //! Does whatever should happen when the threshold is reached
     /** This should be very fast or else spawn a task.  This is
         called while the sender is blocked in the try_put(). */
-    virtual void execute() = 0;
-        
+    virtual task * execute() = 0;
+    template<typename TT, typename M>
+        friend class internal::successor_cache;
+    /*override*/ bool is_continue_receiver() { return true; }
 };
+}  // interface7
+}  // flow
+}  // tbb
+
+#include "internal/_flow_graph_trace_impl.h"
+
+namespace tbb {
+namespace flow {
+namespace interface7 {
 
+#include "internal/_flow_graph_types_impl.h"
 #include "internal/_flow_graph_impl.h"
 using namespace internal::graph_policy_namespace;
 
+class graph;
+class graph_node;
+
+template <typename GraphContainerType, typename GraphNodeType>
+class graph_iterator {
+    friend class graph;
+    friend class graph_node;
+public:
+    typedef size_t size_type;
+    typedef GraphNodeType value_type;
+    typedef GraphNodeType* pointer;
+    typedef GraphNodeType& reference;
+    typedef const GraphNodeType& const_reference;
+    typedef std::forward_iterator_tag iterator_category;
+
+    //! Default constructor
+    graph_iterator() : my_graph(NULL), current_node(NULL) {}
+
+    //! Copy constructor
+    graph_iterator(const graph_iterator& other) :
+        my_graph(other.my_graph), current_node(other.current_node)
+    {}
+
+    //! Assignment
+    graph_iterator& operator=(const graph_iterator& other) {
+        if (this != &other) {
+            my_graph = other.my_graph;
+            current_node = other.current_node;
+        }
+        return *this;
+    }
+
+    //! Dereference
+    reference operator*() const;
+
+    //! Dereference
+    pointer operator->() const;
+
+    //! Equality
+    bool operator==(const graph_iterator& other) const {
+        return ((my_graph == other.my_graph) && (current_node == other.current_node));
+    }
+
+    //! Inequality
+    bool operator!=(const graph_iterator& other) const { return !(operator==(other)); }
+
+    //! Pre-increment
+    graph_iterator& operator++() {
+        internal_forward();
+        return *this;
+    }
+
+    //! Post-increment
+    graph_iterator operator++(int) {
+        graph_iterator result = *this;
+        operator++();
+        return result;
+    }
+
+private:
+    // the graph over which we are iterating
+    GraphContainerType *my_graph;
+    // pointer into my_graph's my_nodes list
+    pointer current_node;
+
+    //! Private initializing constructor for begin() and end() iterators
+    graph_iterator(GraphContainerType *g, bool begin);
+    void internal_forward();
+};
+
 //! The graph class
 /** This class serves as a handle to the graph */
 class graph : tbb::internal::no_copy {
-        
+    friend class graph_node;
+
     template< typename Body >
     class run_task : public task {
-    public: 
+    public:
         run_task( Body& body ) : my_body(body) {}
         task *execute() {
             my_body();
@@ -229,168 +471,401 @@ class graph : tbb::internal::no_copy {
     private:
         Body my_body;
     };
-        
+
     template< typename Receiver, typename Body >
     class run_and_put_task : public task {
-    public: 
+    public:
         run_and_put_task( Receiver &r, Body& body ) : my_receiver(r), my_body(body) {}
         task *execute() {
-            my_receiver.try_put( my_body() );
-            return NULL;
+            task *res = my_receiver.try_put_task( my_body() );
+            if(res == SUCCESSFULLY_ENQUEUED) res = NULL;
+            return res;
         }
     private:
         Receiver &my_receiver;
         Body my_body;
     };
-        
+
 public:
-        
-        
-    //! Constructs a graph withy no nodes.
-    graph() : my_root_task( new ( task::allocate_root( ) ) empty_task ) {
+    //! Constructs a graph with isolated task_group_context
+    explicit graph() : my_nodes(NULL), my_nodes_last(NULL)
+    {
+        own_context = true;
+        cancelled = false;
+        caught_exception = false;
+        my_context = new task_group_context();
+        my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task );
+        my_root_task->set_ref_count(1);
+        tbb::internal::fgt_graph( this );
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_is_active = true;
+#endif
+    }
+
+    //! Constructs a graph with use_this_context as context
+    explicit graph(task_group_context& use_this_context) :
+    my_context(&use_this_context), my_nodes(NULL), my_nodes_last(NULL)
+    {
+        own_context = false;
+        my_root_task = ( new ( task::allocate_root(*my_context) ) empty_task );
         my_root_task->set_ref_count(1);
+        tbb::internal::fgt_graph( this );
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_is_active = true;
+#endif
     }
-        
+
     //! Destroys the graph.
-    /** Calls wait_for_all on the graph, deletes all of the nodes appended by calls to add, and then 
-        destroys the root task of the graph. */ 
+    /** Calls wait_for_all, then destroys the root task and context. */
     ~graph() {
         wait_for_all();
         my_root_task->set_ref_count(0);
         task::destroy( *my_root_task );
+        if (own_context) delete my_context;
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    void set_name( const char *name ) {
+        tbb::internal::fgt_graph_desc( this, name );
     }
-        
-        
+#endif
+
     //! Used to register that an external entity may still interact with the graph.
     /** The graph will not return from wait_for_all until a matching number of decrement_wait_count calls
         is made. */
-    void increment_wait_count() { 
+    void increment_wait_count() {
         if (my_root_task)
             my_root_task->increment_ref_count();
     }
-        
+
     //! Deregisters an external entity that may have interacted with the graph.
     /** The graph will not return from wait_for_all until all the number of decrement_wait_count calls
         matches the number of increment_wait_count calls. */
-    void decrement_wait_count() { 
+    void decrement_wait_count() {
         if (my_root_task)
-            my_root_task->decrement_ref_count(); 
+            my_root_task->decrement_ref_count();
     }
-        
+
     //! Spawns a task that runs a body and puts its output to a specific receiver
-    /** The task is spawned as a child of the graph. This is useful for running tasks 
+    /** The task is spawned as a child of the graph. This is useful for running tasks
         that need to block a wait_for_all() on the graph.  For example a one-off source. */
     template< typename Receiver, typename Body >
         void run( Receiver &r, Body body ) {
-       task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-           run_and_put_task< Receiver, Body >( r, body ) );
+       FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *my_root_task ) )
+                   run_and_put_task< Receiver, Body >( r, body )) );
     }
-        
-    //! Spawns a task that runs a function object 
-    /** The task is spawned as a child of the graph. This is useful for running tasks 
+
+    //! Spawns a task that runs a function object
+    /** The task is spawned as a child of the graph. This is useful for running tasks
         that need to block a wait_for_all() on the graph. For example a one-off source. */
     template< typename Body >
     void run( Body body ) {
-       task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-           run_task< Body >( body ) );
+       FLOW_SPAWN( * new ( task::allocate_additional_child_of( *my_root_task ) ) run_task< Body >( body ) );
     }
-        
-    //! Waits until the graph is idle and the number of decrement_wait_count calls equals the number of increment_wait_count calls.
+
+    //! Wait until graph is idle and decrement_wait_count calls equals increment_wait_count calls.
     /** The waiting thread will go off and steal work while it is block in the wait_for_all. */
     void wait_for_all() {
-        if (my_root_task)
-            my_root_task->wait_for_all();
-        my_root_task->set_ref_count(1);
+        cancelled = false;
+        caught_exception = false;
+        if (my_root_task) {
+#if TBB_USE_EXCEPTIONS
+            try {
+#endif
+                my_root_task->wait_for_all();
+                cancelled = my_context->is_group_execution_cancelled();
+#if TBB_USE_EXCEPTIONS
+            }
+            catch(...) {
+                my_root_task->set_ref_count(1);
+                my_context->reset();
+                caught_exception = true;
+                cancelled = true;
+                throw;
+            }
+#endif
+            my_context->reset();  // consistent with behavior in catch()
+            my_root_task->set_ref_count(1);
+        }
     }
-        
+
     //! Returns the root task of the graph
     task * root_task() {
-        return my_root_task;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        if (!my_is_active) 
+            return NULL;
+        else
+#endif
+            return my_root_task;
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    void set_active(bool a = true) {
+       my_is_active = a;
+    }
+
+    bool is_active() {
+       return my_is_active;
     }
-        
+#endif
+
+    // ITERATORS
+    template<typename C, typename N>
+    friend class graph_iterator;
+
+    // Graph iterator typedefs
+    typedef graph_iterator<graph,graph_node> iterator;
+    typedef graph_iterator<const graph,const graph_node> const_iterator;
+
+    // Graph iterator constructors
+    //! start iterator
+    iterator begin() { return iterator(this, true); }
+    //! end iterator
+    iterator end() { return iterator(this, false); }
+     //! start const iterator
+    const_iterator begin() const { return const_iterator(this, true); }
+    //! end const iterator
+    const_iterator end() const { return const_iterator(this, false); }
+    //! start const iterator
+    const_iterator cbegin() const { return const_iterator(this, true); }
+    //! end const iterator
+    const_iterator cend() const { return const_iterator(this, false); }
+
+    //! return status of graph execution
+    bool is_cancelled() { return cancelled; }
+    bool exception_thrown() { return caught_exception; }
+
+    // thread-unsafe state reset.
+    void reset(__TBB_PFG_RESET_ARG(reset_flags f = rf_reset_protocol));
+
 private:
-        
     task *my_root_task;
-        
+    task_group_context *my_context;
+    bool own_context;
+    bool cancelled;
+    bool caught_exception;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    bool my_is_active;
+#endif
+
+
+    graph_node *my_nodes, *my_nodes_last;
+
+    spin_mutex nodelist_mutex;
+    void register_node(graph_node *n);
+    void remove_node(graph_node *n);
+
+};  // class graph
+
+template <typename C, typename N>
+graph_iterator<C,N>::graph_iterator(C *g, bool begin) : my_graph(g), current_node(NULL)
+{
+    if (begin) current_node = my_graph->my_nodes;
+    //else it is an end iterator by default
+}
+
+template <typename C, typename N>
+typename graph_iterator<C,N>::reference graph_iterator<C,N>::operator*() const {
+    __TBB_ASSERT(current_node, "graph_iterator at end");
+    return *operator->();
+}
+
+template <typename C, typename N>
+typename graph_iterator<C,N>::pointer graph_iterator<C,N>::operator->() const {
+    return current_node;
+}
+
+
+template <typename C, typename N>
+void graph_iterator<C,N>::internal_forward() {
+    if (current_node) current_node = current_node->next;
+}
+
+//! The base of all graph nodes.
+class graph_node : tbb::internal::no_assign {
+    friend class graph;
+    template<typename C, typename N>
+    friend class graph_iterator;
+protected:
+    graph& my_graph;
+    graph_node *next, *prev;
+public:
+    graph_node(graph& g) : my_graph(g) {
+        my_graph.register_node(this);
+    }
+    virtual ~graph_node() {
+        my_graph.remove_node(this);
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    virtual void set_name( const char *name ) = 0;
+#endif
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    virtual void extract( reset_flags f=rf_extract ) {
+        bool a = my_graph.is_active();
+        my_graph.set_active(false);
+        reset((reset_flags)(f|rf_extract));
+        my_graph.set_active(a);
+    }
+#endif
+
+protected:
+    virtual void reset(__TBB_PFG_RESET_ARG(reset_flags f=rf_reset_protocol)) = 0;
 };
 
+inline void graph::register_node(graph_node *n) {
+    n->next = NULL;
+    {
+        spin_mutex::scoped_lock lock(nodelist_mutex);
+        n->prev = my_nodes_last;
+        if (my_nodes_last) my_nodes_last->next = n;
+        my_nodes_last = n;
+        if (!my_nodes) my_nodes = n;
+    }
+}
+
+inline void graph::remove_node(graph_node *n) {
+    {
+        spin_mutex::scoped_lock lock(nodelist_mutex);
+        __TBB_ASSERT(my_nodes && my_nodes_last, "graph::remove_node: Error: no registered nodes");
+        if (n->prev) n->prev->next = n->next;
+        if (n->next) n->next->prev = n->prev;
+        if (my_nodes_last == n) my_nodes_last = n->prev;
+        if (my_nodes == n) my_nodes = n->next;
+    }
+    n->prev = n->next = NULL;
+}
+
+inline void graph::reset( __TBB_PFG_RESET_ARG( reset_flags f )) {
+    // reset context
+    task *saved_my_root_task = my_root_task;
+    my_root_task = NULL;
+    if(my_context) my_context->reset();
+    cancelled = false;
+    caught_exception = false;
+    // reset all the nodes comprising the graph
+    for(iterator ii = begin(); ii != end(); ++ii) {
+        graph_node *my_p = &(*ii);
+        my_p->reset(__TBB_PFG_RESET_ARG(f));
+    }
+    my_root_task = saved_my_root_task;
+}
+
+
 #include "internal/_flow_graph_node_impl.h"
 
 //! An executable node that acts as a source, i.e. it has no predecessors
 template < typename Output >
 class source_node : public graph_node, public sender< Output > {
+protected:
+    using graph_node::my_graph;
 public:
-        
     //! The type of the output message, which is complete
-    typedef Output output_type;           
-        
+    typedef Output output_type;
+
     //! The type of successors of this node
     typedef receiver< Output > successor_type;
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    typedef std::vector<successor_type *> successor_vector_type;
+#endif
+
     //! Constructor for a node with a successor
     template< typename Body >
     source_node( graph &g, Body body, bool is_active = true )
-        : my_root_task(g.root_task()), my_active(is_active), init_my_active(is_active),
+        : graph_node(g), my_active(is_active), init_my_active(is_active),
         my_body( new internal::source_body_leaf< output_type, Body>(body) ),
-        my_reserved(false), my_has_cached_item(false) 
-    { 
+        my_reserved(false), my_has_cached_item(false)
+    {
         my_successors.set_owner(this);
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_SOURCE_NODE, &this->my_graph,
+                                           static_cast<sender<output_type> *>(this), this->my_body );
     }
-        
+
     //! Copy constructor
     source_node( const source_node& src ) :
-        graph_node(), sender<Output>(),
-        my_root_task( src.my_root_task), my_active(src.init_my_active),
+        graph_node(src.my_graph), sender<Output>(),
+        my_active(src.init_my_active),
         init_my_active(src.init_my_active), my_body( src.my_body->clone() ),
         my_reserved(false), my_has_cached_item(false)
     {
         my_successors.set_owner(this);
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_SOURCE_NODE, &this->my_graph,
+                                           static_cast<sender<output_type> *>(this), this->my_body );
     }
 
     //! The destructor
     ~source_node() { delete my_body; }
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
     //! Add a new successor to this node
-    /* override */ bool register_successor( receiver<output_type> &r ) {
+    /* override */ bool register_successor( successor_type &r ) {
         spin_mutex::scoped_lock lock(my_mutex);
         my_successors.register_successor(r);
         if ( my_active )
             spawn_put();
         return true;
     }
-        
+
     //! Removes a successor from this node
-    /* override */ bool remove_successor( receiver<output_type> &r ) {
+    /* override */ bool remove_successor( successor_type &r ) {
         spin_mutex::scoped_lock lock(my_mutex);
         my_successors.remove_successor(r);
         return true;
     }
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    /*override*/void internal_add_built_successor( successor_type &r) {
+        spin_mutex::scoped_lock lock(my_mutex);
+        my_successors.internal_add_built_successor(r);
+    }
+
+    /*override*/void internal_delete_built_successor( successor_type &r) {
+        spin_mutex::scoped_lock lock(my_mutex);
+        my_successors.internal_delete_built_successor(r);
+    }
+
+    /*override*/size_t successor_count() {
+        spin_mutex::scoped_lock lock(my_mutex);
+        return my_successors.successor_count();
+    }
+
+    /*override*/void copy_successors(successor_vector_type &v) {
+        spin_mutex::scoped_lock l(my_mutex);
+        my_successors.copy_successors(v);
+    }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
     //! Request an item from the node
     /*override */ bool try_get( output_type &v ) {
         spin_mutex::scoped_lock lock(my_mutex);
-        if ( my_reserved )  
+        if ( my_reserved )
             return false;
-        
+
         if ( my_has_cached_item ) {
             v = my_cached_item;
             my_has_cached_item = false;
-        } else if ( (*my_body)(v) == false ) {
-            return false;
+            return true;
         }
-        return true;
+        // we've been asked to provide an item, but we have none.  enqueue a task to
+        // provide one.
+        spawn_put();
+        return false;
     }
-        
+
     //! Reserves an item.
     /* override */ bool try_reserve( output_type &v ) {
         spin_mutex::scoped_lock lock(my_mutex);
         if ( my_reserved ) {
             return false;
         }
-        
-        if ( !my_has_cached_item && (*my_body)(my_cached_item) )  
-            my_has_cached_item = true;
-        
+
         if ( my_has_cached_item ) {
             v = my_cached_item;
             my_reserved = true;
@@ -399,17 +874,18 @@ public:
             return false;
         }
     }
-        
-    //! Release a reserved item.  
-    /**  true = item has been released and so remains in sender, dest must request or reserve future items */
+
+    //! Release a reserved item.
+    /** true = item has been released and so remains in sender, dest must request or reserve future items */
     /* override */ bool try_release( ) {
         spin_mutex::scoped_lock lock(my_mutex);
         __TBB_ASSERT( my_reserved && my_has_cached_item, "releasing non-existent reservation" );
         my_reserved = false;
-        spawn_put();
+        if(!my_successors.empty())
+            spawn_put();
         return true;
     }
-        
+
     //! Consumes a reserved item
     /* override */ bool try_consume( ) {
         spin_mutex::scoped_lock lock(my_mutex);
@@ -421,7 +897,7 @@ public:
         }
         return true;
     }
-        
+
     //! Activates a node that was created in the inactive state
     void activate() {
         spin_mutex::scoped_lock lock(my_mutex);
@@ -429,74 +905,150 @@ public:
         if ( !my_successors.empty() )
             spawn_put();
     }
-        
-private:
-        
-    task *my_root_task;
-    spin_mutex my_mutex;
-    bool my_active;
-    bool init_my_active;
-    internal::source_body<output_type> *my_body;
-    internal::broadcast_cache< output_type > my_successors;
-    bool my_reserved;
-    bool my_has_cached_item;
-    output_type my_cached_item;
-        
-    friend class internal::source_task< source_node< output_type > >;
-        
-    //! Applies the body
-    /* override */ void apply_body( ) {
+
+    template<typename Body>
+    Body copy_function_object() {
+        internal::source_body<output_type> &body_ref = *this->my_body;
+        return dynamic_cast< internal::source_body_leaf<output_type, Body> & >(body_ref).get_body();
+    }
+
+protected:
+
+    //! resets the source_node to its initial state
+    void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        my_active = init_my_active;
+        my_reserved =false;
+        if(my_has_cached_item) {
+            my_has_cached_item = false;
+        }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_successors.reset(f);
+        if(f & rf_reset_bodies) my_body->reset_body();
+#endif
+    }
+
+private:
+    spin_mutex my_mutex;
+    bool my_active;
+    bool init_my_active;
+    internal::source_body<output_type> *my_body;
+    internal::broadcast_cache< output_type > my_successors;
+    bool my_reserved;
+    bool my_has_cached_item;
+    output_type my_cached_item;
+
+    // used by apply_body, can invoke body of node.
+    bool try_reserve_apply_body(output_type &v) {
+        spin_mutex::scoped_lock lock(my_mutex);
+        if ( my_reserved ) {
+            return false;
+        }
+        if ( !my_has_cached_item ) {
+            tbb::internal::fgt_begin_body( my_body );
+            bool r = (*my_body)(my_cached_item);
+            tbb::internal::fgt_end_body( my_body );
+            if (r) {
+                my_has_cached_item = true;
+            }
+        }
+        if ( my_has_cached_item ) {
+            v = my_cached_item;
+            my_reserved = true;
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    //! Spawns a task that applies the body
+    /* override */ void spawn_put( ) {
+        task* tp = this->my_graph.root_task();
+        if(tp) {
+            FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *tp ) )
+                        internal:: source_task_bypass < source_node< output_type > >( *this ) ) );
+        }
+    }
+
+    friend class internal::source_task_bypass< source_node< output_type > >;
+    //! Applies the body.  Returning SUCCESSFULLY_ENQUEUED okay; forward_task_bypass will handle it.
+    /* override */ task * apply_body_bypass( ) {
         output_type v;
-        if ( try_reserve(v) == false )
-            return;
-        
-        if ( my_successors.try_put( v ) ) 
+        if ( !try_reserve_apply_body(v) )
+            return NULL;
+
+        task *last_task = my_successors.try_put_task(v);
+        if ( last_task )
             try_consume();
         else
             try_release();
+        return last_task;
     }
-        
-    //! Spawns a task that applies the body
-    /* override */ void spawn_put( ) {
-        task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-           internal::source_task< source_node< output_type > >( *this ) ); 
-    }
-        
-};
-        
+};  // source_node
+
 //! Implements a function node that supports Input -> Output
 template < typename Input, typename Output = continue_msg, graph_buffer_policy = queueing, typename Allocator=cache_aligned_allocator<Input> >
 class function_node : public graph_node, public internal::function_input<Input,Output,Allocator>, public internal::function_output<Output> {
+protected:
+    using graph_node::my_graph;
 public:
-        
     typedef Input input_type;
     typedef Output output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
+    typedef internal::function_input<input_type,output_type,Allocator> fInput_type;
     typedef internal::function_output<output_type> fOutput_type;
-        
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    using typename internal::function_input<Input,Output,Allocator>::predecessor_vector_type;
+    using typename internal::function_output<Output>::successor_vector_type;
+#endif
+
     //! Constructor
     template< typename Body >
-    function_node( graph &g, size_t concurrency, Body body )
-    : internal::function_input<input_type,output_type,Allocator>( g, concurrency, body ) {
+    function_node( graph &g, size_t concurrency, Body body ) :
+        graph_node(g), internal::function_input<input_type,output_type,Allocator>(g, concurrency, body) {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
     }
 
     //! Copy constructor
-    function_node( const function_node& src ) : 
-        graph_node(), internal::function_input<input_type,output_type,Allocator>( src ),
-        fOutput_type() {}
-        
+    function_node( const function_node& src ) :
+        graph_node(src.my_graph), internal::function_input<input_type,output_type,Allocator>( src ),
+        fOutput_type() {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->my_graph, static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
 protected:
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    using fInput_type::try_put_task;
+
+    // override of graph_node's reset.
+    /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) {
+        fInput_type::reset_function_input(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        successors().reset(f);
+        __TBB_ASSERT(!(f & rf_extract) || successors().empty(), "function_node successors not empty");
+        __TBB_ASSERT(this->my_predecessors.empty(), "function_node predecessors not empty");
+#endif
+    }
 
     /* override */ internal::broadcast_cache<output_type> &successors () { return fOutput_type::my_successors; }
-        
 };
 
 //! Implements a function node that supports Input -> Output
 template < typename Input, typename Output, typename Allocator >
 class function_node<Input,Output,queueing,Allocator> : public graph_node, public internal::function_input<Input,Output,Allocator>, public internal::function_output<Output> {
+protected:
+    using graph_node::my_graph;
 public:
-        
     typedef Input input_type;
     typedef Output output_type;
     typedef sender< input_type > predecessor_type;
@@ -504,164 +1056,287 @@ public:
     typedef internal::function_input<input_type,output_type,Allocator> fInput_type;
     typedef internal::function_input_queue<input_type, Allocator> queue_type;
     typedef internal::function_output<output_type> fOutput_type;
-        
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    using typename internal::function_input<Input,Output,Allocator>::predecessor_vector_type;
+    using typename internal::function_output<Output>::successor_vector_type;
+#endif
+
     //! Constructor
     template< typename Body >
-    function_node( graph &g, size_t concurrency, Body body ) : fInput_type( g, concurrency, body, new queue_type() ) {
+    function_node( graph &g, size_t concurrency, Body body ) :
+        graph_node(g), fInput_type( g, concurrency, body, new queue_type() ) {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
     }
 
     //! Copy constructor
-    function_node( const function_node& src ) : 
-        graph_node(), fInput_type( src, new queue_type() ) , fOutput_type() { }
+    function_node( const function_node& src ) :
+        graph_node(src.graph_node::my_graph), fInput_type( src, new queue_type() ), fOutput_type() {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_FUNCTION_NODE, &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
 
 protected:
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    using fInput_type::try_put_task;
+
+    /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        fInput_type::reset_function_input(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        successors().reset(f);
+        __TBB_ASSERT(!(f & rf_extract) || successors().empty(), "function_node successors not empty");
+        __TBB_ASSERT(!(f & rf_extract) || this->my_predecessors.empty(), "function_node predecessors not empty");
+#endif
+
+    }
 
     /* override */ internal::broadcast_cache<output_type> &successors () { return fOutput_type::my_successors; }
-        
 };
 
-#include "tbb/internal/_flow_graph_types_impl.h"
-
-#if TBB_PREVIEW_GRAPH_NODES
 //! implements a function node that supports Input -> (set of outputs)
 // Output is a tuple of output types.
 template < typename Input, typename Output, graph_buffer_policy = queueing, typename Allocator=cache_aligned_allocator<Input> >
-class multioutput_function_node : 
-    public graph_node, 
-    public internal::multioutput_function_input
-    <  
-        Input, 
+class multifunction_node :
+    public graph_node,
+    public internal::multifunction_input
+    <
+        Input,
         typename internal::wrap_tuple_elements<
-            std::tuple_size<Output>::value,  // #elements in tuple
-            internal::function_output,  // wrap this around each element
+            tbb::flow::tuple_size<Output>::value,  // #elements in tuple
+            internal::multifunction_output,  // wrap this around each element
             Output // the tuple providing the types
         >::type,
         Allocator
     > {
+protected:
+    using graph_node::my_graph;
 private:
-    static const int N = std::tuple_size<Output>::value;
+    static const int N = tbb::flow::tuple_size<Output>::value;
 public:
     typedef Input input_type;
-    typedef typename internal::wrap_tuple_elements<N,internal::function_output, Output>::type ports_type;
+    typedef typename internal::wrap_tuple_elements<N,internal::multifunction_output, Output>::type output_ports_type;
 private:
-    typedef typename internal::multioutput_function_input<input_type, ports_type, Allocator> base_type;
+    typedef typename internal::multifunction_input<input_type, output_ports_type, Allocator> base_type;
     typedef typename internal::function_input_queue<input_type,Allocator> queue_type;
 public:
     template<typename Body>
-    multioutput_function_node( graph &g, size_t concurrency, Body body ) : base_type(g,concurrency, body) {}
-    multioutput_function_node( const multioutput_function_node &other) :
-        graph_node(), base_type(other) {}
-    // all the guts are in multioutput_function_input...
+    multifunction_node( graph &g, size_t concurrency, Body body ) :
+        graph_node(g), base_type(g,concurrency, body) {
+        tbb::internal::fgt_multioutput_node_with_body<Output,N>( tbb::internal::FLOW_MULTIFUNCTION_NODE,
+                                                                 &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                                                 this->output_ports(), this->my_body );
+    }
+
+    multifunction_node( const multifunction_node &other) :
+        graph_node(other.graph_node::my_graph), base_type(other) {
+        tbb::internal::fgt_multioutput_node_with_body<Output,N>( tbb::internal::FLOW_MULTIFUNCTION_NODE,
+                                                                 &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                                                 this->output_ports(), this->my_body );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_multioutput_node_desc( this, name );
+    }
+#endif
+
+    // all the guts are in multifunction_input...
+protected:
+    /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset(__TBB_PFG_RESET_ARG(f)); }
+};  // multifunction_node
 
-};  // multioutput_function_node
-        
 template < typename Input, typename Output, typename Allocator >
-class multioutput_function_node<Input,Output,queueing,Allocator> : public graph_node, public internal::multioutput_function_input<Input, 
-    typename internal::wrap_tuple_elements<std::tuple_size<Output>::value, internal::function_output, Output>::type, Allocator> {
-    static const int N = std::tuple_size<Output>::value;
+class multifunction_node<Input,Output,queueing,Allocator> : public graph_node, public internal::multifunction_input<Input,
+    typename internal::wrap_tuple_elements<tbb::flow::tuple_size<Output>::value, internal::multifunction_output, Output>::type, Allocator> {
+protected:
+    using graph_node::my_graph;
+    static const int N = tbb::flow::tuple_size<Output>::value;
 public:
     typedef Input input_type;
-    typedef typename internal::wrap_tuple_elements<N, internal::function_output, Output>::type ports_type;
+    typedef typename internal::wrap_tuple_elements<N, internal::multifunction_output, Output>::type output_ports_type;
 private:
-    typedef typename internal::multioutput_function_input<input_type, ports_type, Allocator> base_type;
+    typedef typename internal::multifunction_input<input_type, output_ports_type, Allocator> base_type;
     typedef typename internal::function_input_queue<input_type,Allocator> queue_type;
 public:
-
     template<typename Body>
-    multioutput_function_node( graph &g, size_t concurrency, Body body) : base_type(g,concurrency, body, new queue_type()) {}
-    multioutput_function_node( const multioutput_function_node &other) :
-        graph_node(), base_type(other, new queue_type()) {}
+    multifunction_node( graph &g, size_t concurrency, Body body) :
+        graph_node(g), base_type(g,concurrency, body, new queue_type()) {
+        tbb::internal::fgt_multioutput_node_with_body<Output,N>( tbb::internal::FLOW_MULTIFUNCTION_NODE,
+                                                                 &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                                                 this->output_ports(), this->my_body );
+    }
+
+    multifunction_node( const multifunction_node &other) :
+        graph_node(other.graph_node::my_graph), base_type(other, new queue_type()) {
+        tbb::internal::fgt_multioutput_node_with_body<Output,N>( tbb::internal::FLOW_MULTIFUNCTION_NODE,
+                                                                 &this->graph_node::my_graph, static_cast<receiver<input_type> *>(this),
+                                                                 this->output_ports(), this->my_body );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_multioutput_node_desc( this, name );
+    }
+#endif
 
-};  // multioutput_function_node
+    // all the guts are in multifunction_input...
+protected:
+    /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { base_type::reset(__TBB_PFG_RESET_ARG(f)); }
+};  // multifunction_node
 
 //! split_node: accepts a tuple as input, forwards each element of the tuple to its
 //  successors.  The node has unlimited concurrency, so though it is marked as
 //  "rejecting" it does not reject inputs.
 template<typename TupleType, typename Allocator=cache_aligned_allocator<TupleType> >
-class split_node : public multioutput_function_node<TupleType, TupleType, rejecting, Allocator> {
-    static const int N = std::tuple_size<TupleType>::value;
-    typedef multioutput_function_node<TupleType,TupleType,rejecting,Allocator> base_type;
+class split_node : public multifunction_node<TupleType, TupleType, rejecting, Allocator> {
+    static const int N = tbb::flow::tuple_size<TupleType>::value;
+    typedef multifunction_node<TupleType,TupleType,rejecting,Allocator> base_type;
 public:
-    typedef typename base_type::ports_type ports_type;
+    typedef typename base_type::output_ports_type output_ports_type;
 private:
-
     struct splitting_body {
-        void operator()(const TupleType& t, ports_type &p) {
+        void operator()(const TupleType& t, output_ports_type &p) {
             internal::emit_element<N>::emit_this(t, p);
         }
     };
 public:
     typedef TupleType input_type;
     typedef Allocator allocator_type;
-    split_node(graph &g) : base_type(g, unlimited, splitting_body()) { }
-    split_node( const split_node & other) : base_type(other) { }
+    split_node(graph &g) : base_type(g, unlimited, splitting_body()) {
+        tbb::internal::fgt_multioutput_node<TupleType,N>( tbb::internal::FLOW_SPLIT_NODE, &this->graph_node::my_graph,
+                                                          static_cast<receiver<input_type> *>(this), this->output_ports() );
+    }
+
+    split_node( const split_node & other) : base_type(other) {
+        tbb::internal::fgt_multioutput_node<TupleType,N>( tbb::internal::FLOW_SPLIT_NODE, &this->graph_node::my_graph,
+                                                          static_cast<receiver<input_type> *>(this), this->output_ports() );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_multioutput_node_desc( this, name );
+    }
+#endif
+
 };
-#endif  // TBB_PREVIEW_GRAPH_NODES
 
 //! Implements an executable node that supports continue_msg -> Output
 template <typename Output>
 class continue_node : public graph_node, public internal::continue_input<Output>, public internal::function_output<Output> {
+protected:
+    using graph_node::my_graph;
 public:
-        
     typedef continue_msg input_type;
     typedef Output output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
+    typedef internal::continue_input<Output> fInput_type;
     typedef internal::function_output<output_type> fOutput_type;
-        
-     //! Constructor for executable node with continue_msg -> Output
-     template <typename Body >
-     continue_node( graph &g, Body body )
-             : internal::continue_input<output_type>( g, body ) {
-     }
-        
+
     //! Constructor for executable node with continue_msg -> Output
     template <typename Body >
-    continue_node( graph &g, int number_of_predecessors, Body body )
-        : internal::continue_input<output_type>( g, number_of_predecessors, body )
-    {
+    continue_node( graph &g, Body body ) :
+        graph_node(g), internal::continue_input<output_type>( g, body ) {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph,
+                                           static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
+    }
+
+
+    //! Constructor for executable node with continue_msg -> Output
+    template <typename Body >
+    continue_node( graph &g, int number_of_predecessors, Body body ) :
+        graph_node(g), internal::continue_input<output_type>( g, number_of_predecessors, body ) {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph,
+                                           static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
     }
-    //! Copy constructor       
+
+    //! Copy constructor
     continue_node( const continue_node& src ) :
-        graph_node(), internal::continue_input<output_type>(src),
-        internal::function_output<Output>() { }
+        graph_node(src.graph_node::my_graph), internal::continue_input<output_type>(src),
+        internal::function_output<Output>() {
+        tbb::internal::fgt_node_with_body( tbb::internal::FLOW_CONTINUE_NODE, &this->my_graph,
+                                           static_cast<receiver<input_type> *>(this),
+                                           static_cast<sender<output_type> *>(this), this->my_body );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
 
 protected:
-        
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    using fInput_type::try_put_task;
+
+    /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) {
+        fInput_type::reset_receiver(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        successors().reset(f);
+        __TBB_ASSERT(!(f & rf_extract) || successors().empty(), "continue_node not reset");
+#endif
+    }
+
     /* override */ internal::broadcast_cache<output_type> &successors () { return fOutput_type::my_successors; }
-        
-};
-        
+};  // continue_node
+
 template< typename T >
 class overwrite_node : public graph_node, public receiver<T>, public sender<T> {
+protected:
+    using graph_node::my_graph;
 public:
-        
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
-    overwrite_node() : my_buffer_is_valid(false) {
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    typedef std::vector<predecessor_type *> predecessor_vector_type;
+    typedef std::vector<successor_type *> successor_vector_type;
+#endif
+
+    overwrite_node(graph &g) : graph_node(g), my_buffer_is_valid(false) {
         my_successors.set_owner( this );
+        tbb::internal::fgt_node( tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
     }
 
     // Copy constructor; doesn't take anything from src; default won't work
-    overwrite_node( const overwrite_node& ) : 
-        graph_node(), receiver<T>(), sender<T>(), my_buffer_is_valid(false) {
+    overwrite_node( const overwrite_node& src ) :
+        graph_node(src.my_graph), receiver<T>(), sender<T>(), my_buffer_is_valid(false)
+    {
         my_successors.set_owner( this );
+        tbb::internal::fgt_node( tbb::internal::FLOW_OVERWRITE_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
     }
-        
+
     ~overwrite_node() {}
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
     /* override */ bool register_successor( successor_type &s ) {
         spin_mutex::scoped_lock l( my_mutex );
-        if ( my_buffer_is_valid ) {
+        task* tp = this->my_graph.root_task();  // just to test if we are resetting
+        if (my_buffer_is_valid && tp) {
             // We have a valid value that must be forwarded immediately.
             if ( s.try_put( my_buffer ) || !s.register_predecessor( *this  ) ) {
-                // We add the successor: it accepted our put or it rejected it but won't let use become a predecessor
+                // We add the successor: it accepted our put or it rejected it but won't let us become a predecessor
                 my_successors.register_successor( s );
-                return true;
             } else {
                 // We don't add the successor: it rejected our put and we became its predecessor instead
                 return false;
@@ -669,162 +1344,340 @@ public:
         } else {
             // No valid value yet, just add as successor
             my_successors.register_successor( s );
-            return true;
         }
+        return true;
     }
-        
+
     /* override */ bool remove_successor( successor_type &s ) {
         spin_mutex::scoped_lock l( my_mutex );
         my_successors.remove_successor(s);
         return true;
     }
-        
-    /* override */ bool try_put( const T &v ) {
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    /*override*/void internal_add_built_successor( successor_type &s) {
         spin_mutex::scoped_lock l( my_mutex );
-        my_buffer = v;
-        my_buffer_is_valid = true;
-        my_successors.try_put(v);
-        return true;
+        my_successors.internal_add_built_successor(s);
     }
-        
-    /* override */ bool try_get( T &v ) {
+
+    /*override*/void internal_delete_built_successor( successor_type &s) {
+        spin_mutex::scoped_lock l( my_mutex );
+        my_successors.internal_delete_built_successor(s);
+    }
+
+    /*override*/size_t successor_count() {
+        spin_mutex::scoped_lock l( my_mutex );
+        return my_successors.successor_count();
+    }
+
+    /*override*/ void copy_successors(successor_vector_type &v) {
+        spin_mutex::scoped_lock l( my_mutex );
+        my_successors.copy_successors(v);
+    }
+
+    /*override*/ void internal_add_built_predecessor( predecessor_type &p) {
+        spin_mutex::scoped_lock l( my_mutex );
+        my_built_predecessors.add_edge(p);
+    }
+
+    /*override*/ void internal_delete_built_predecessor( predecessor_type &p) {
+        spin_mutex::scoped_lock l( my_mutex );
+        my_built_predecessors.delete_edge(p);
+    }
+
+    /*override*/size_t predecessor_count() {
+        spin_mutex::scoped_lock l( my_mutex );
+        return my_built_predecessors.edge_count();
+    }
+
+    /*override*/void copy_predecessors(predecessor_vector_type &v) {
+        spin_mutex::scoped_lock l( my_mutex );
+        my_built_predecessors.copy_edges(v);
+    }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
+    /* override */ bool try_get( input_type &v ) {
         spin_mutex::scoped_lock l( my_mutex );
         if ( my_buffer_is_valid ) {
             v = my_buffer;
             return true;
-        } else {
-            return false;
         }
+        return false;
     }
-        
+
     bool is_valid() {
        spin_mutex::scoped_lock l( my_mutex );
        return my_buffer_is_valid;
     }
-        
+
     void clear() {
        spin_mutex::scoped_lock l( my_mutex );
        my_buffer_is_valid = false;
     }
-        
+
 protected:
-        
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    /* override */ task * try_put_task( const input_type &v ) {
+        spin_mutex::scoped_lock l( my_mutex );
+        my_buffer = v;
+        my_buffer_is_valid = true;
+        task * rtask = my_successors.try_put_task(v);
+        if(!rtask) rtask = SUCCESSFULLY_ENQUEUED;
+        return rtask;
+    }
+
+    /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        my_buffer_is_valid = false;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_successors.reset(f);
+       if (f&rf_extract) {
+           my_built_predecessors.receiver_extract(*this);
+       }
+#endif
+    }
+
     spin_mutex my_mutex;
-    internal::broadcast_cache< T, null_rw_mutex > my_successors;
-    T my_buffer;
+    internal::broadcast_cache< input_type, null_rw_mutex > my_successors;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    edge_container<sender<input_type> > my_built_predecessors;
+#endif
+    input_type my_buffer;
     bool my_buffer_is_valid;
-        
-};
-        
+    /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) {}
+};  // overwrite_node
+
 template< typename T >
 class write_once_node : public overwrite_node<T> {
 public:
-        
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
+
     //! Constructor
-    write_once_node() : overwrite_node<T>() {}
+    write_once_node(graph& g) : overwrite_node<T>(g) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
 
     //! Copy constructor: call base class copy constructor
-    write_once_node( const write_once_node& src ) : overwrite_node<T>(src) {}
+    write_once_node( const write_once_node& src ) : overwrite_node<T>(src) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_WRITE_ONCE_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
 
-    /* override */ bool try_put( const T &v ) {
+protected:
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    /* override */ task *try_put_task( const T &v ) {
         spin_mutex::scoped_lock l( this->my_mutex );
         if ( this->my_buffer_is_valid ) {
-            return false;
+            return NULL;
         } else {
             this->my_buffer = v;
             this->my_buffer_is_valid = true;
-            this->my_successors.try_put(v);
-            return true;
+            task *res = this->my_successors.try_put_task(v);
+            if(!res) res = SUCCESSFULLY_ENQUEUED;
+            return res;
         }
     }
 };
-        
+
 //! Forwards messages of type T to all successors
 template <typename T>
 class broadcast_node : public graph_node, public receiver<T>, public sender<T> {
-        
-    internal::broadcast_cache<T> my_successors;
-        
+protected:
+    using graph_node::my_graph;
 public:
-        
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
-    broadcast_node( ) {
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    typedef std::vector<predecessor_type *> predecessor_vector_type;
+    typedef std::vector<successor_type *> successor_vector_type;
+#endif
+private:
+    internal::broadcast_cache<input_type> my_successors;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    edge_container<predecessor_type> my_built_predecessors;
+    spin_mutex pred_mutex;
+#endif
+public:
+
+    broadcast_node(graph& g) : graph_node(g) {
         my_successors.set_owner( this );
+        tbb::internal::fgt_node( tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
     }
-        
+
     // Copy constructor
-    broadcast_node( const broadcast_node& ) : graph_node(), receiver<T>(), sender<T>() {
+    broadcast_node( const broadcast_node& src ) :
+        graph_node(src.my_graph), receiver<T>(), sender<T>()
+    {
         my_successors.set_owner( this );
+        tbb::internal::fgt_node( tbb::internal::FLOW_BROADCAST_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
     }
-        
+#endif
+
     //! Adds a successor
     virtual bool register_successor( receiver<T> &r ) {
         my_successors.register_successor( r );
         return true;
     }
-        
+
     //! Removes s as a successor
     virtual bool remove_successor( receiver<T> &r ) {
         my_successors.remove_successor( r );
         return true;
     }
-        
-    /* override */ bool try_put( const T &t ) {
-        my_successors.try_put(t);
-        return true;
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    /*override*/ void internal_add_built_successor(successor_type &r) {
+        my_successors.internal_add_built_successor(r);
+    }
+
+    /*override*/ void internal_delete_built_successor(successor_type &r) {
+        my_successors.internal_delete_built_successor(r);
+    }
+
+    /*override*/ size_t successor_count() {
+        return my_successors.successor_count();
+    }
+
+    /*override*/ void copy_successors(successor_vector_type &v) {
+        my_successors.copy_successors(v);
     }
-        
-};
 
-#include "internal/_flow_graph_item_buffer_impl.h"
+    /*override*/ void internal_add_built_predecessor( predecessor_type &p) {
+        my_built_predecessors.add_edge(p);
+    }
+
+    /*override*/ void internal_delete_built_predecessor( predecessor_type &p) {
+        my_built_predecessors.delete_edge(p);
+    }
+
+    /*override*/ size_t predecessor_count() {
+        return my_built_predecessors.edge_count();
+    }
+
+    /*override*/ void copy_predecessors(predecessor_vector_type &v) {
+        my_built_predecessors.copy_edges(v);
+    }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
+protected:
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    //! build a task to run the successor if possible.  Default is old behavior.
+    /*override*/ task *try_put_task(const T& t) {
+        task *new_task = my_successors.try_put_task(t);
+        if(!new_task) new_task = SUCCESSFULLY_ENQUEUED;
+        return new_task;
+    }
+
+    /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) {
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_successors.reset(f);
+        if (f&rf_extract) {
+           my_built_predecessors.receiver_extract(*this);
+        }
+        __TBB_ASSERT(!(f & rf_extract) || my_successors.empty(), "Error resetting broadcast_node");
+#endif
+    }
+    /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) {}
+};  // broadcast_node
 
 //! Forwards messages in arbitrary order
 template <typename T, typename A=cache_aligned_allocator<T> >
-class buffer_node : public graph_node, public reservable_item_buffer<T, A>, public receiver<T>, public sender<T> {
+class buffer_node : public graph_node, public internal::reservable_item_buffer<T, A>, public receiver<T>, public sender<T> {
+protected:
+    using graph_node::my_graph;
 public:
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
     typedef buffer_node<T, A> my_class;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    typedef std::vector<predecessor_type *> predecessor_vector_type;
+    typedef std::vector<successor_type *> successor_vector_type;
+#endif
 protected:
     typedef size_t size_type;
     internal::round_robin_cache< T, null_rw_mutex > my_successors;
-        
-    task *my_parent;
-        
-    friend class internal::forward_task< buffer_node< T, A > >;
-        
-    enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd};
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    edge_container<predecessor_type> my_built_predecessors;
+#endif
+
+    friend class internal::forward_task_bypass< buffer_node< T, A > >;
+
+    enum op_type {reg_succ, rem_succ, req_item, res_item, rel_res, con_res, put_item, try_fwd_task
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        , add_blt_succ, del_blt_succ,
+        add_blt_pred, del_blt_pred,
+        blt_succ_cnt, blt_pred_cnt,
+        blt_succ_cpy, blt_pred_cpy   // create vector copies of preds and succs
+#endif
+    };
     enum op_stat {WAIT=0, SUCCEEDED, FAILED};
-        
+
     // implements the aggregator_operation concept
     class buffer_operation : public internal::aggregated_operation< buffer_operation > {
     public:
         char type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        task * ltask;
+        union {
+            input_type *elem;
+            successor_type *r;
+            predecessor_type *p;
+            size_t cnt_val;
+            successor_vector_type *svec;
+            predecessor_vector_type *pvec;
+        };
+#else
         T *elem;
+        task * ltask;
         successor_type *r;
-        buffer_operation(const T& e, op_type t) :
-            type(char(t)), elem(const_cast<T*>(&e)), r(NULL) {}
-        buffer_operation(op_type t) : type(char(t)), r(NULL) {}
+#endif
+        buffer_operation(const T& e, op_type t) : type(char(t))
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                                                  , ltask(NULL), elem(const_cast<T*>(&e))
+#else
+                                                  , elem(const_cast<T*>(&e)) , ltask(NULL)
+#endif
+        {}
+        buffer_operation(op_type t) : type(char(t)),  ltask(NULL) {}
     };
-        
+
     bool forwarder_busy;
     typedef internal::aggregating_functor<my_class, buffer_operation> my_handler;
     friend class internal::aggregating_functor<my_class, buffer_operation>;
     internal::aggregator< my_handler, buffer_operation> my_aggregator;
-        
+
     virtual void handle_operations(buffer_operation *op_list) {
-        buffer_operation *tmp;
+        buffer_operation *tmp = NULL;
         bool try_forwarding=false;
         while (op_list) {
             tmp = op_list;
@@ -836,65 +1689,152 @@ protected:
             case res_item: internal_reserve(tmp); break;
             case rel_res:  internal_release(tmp);  try_forwarding = true; break;
             case con_res:  internal_consume(tmp);  try_forwarding = true; break;
-            case put_item: internal_push(tmp);  try_forwarding = true; break;
-            case try_fwd:  internal_forward(tmp); break;
+            case put_item: internal_push(tmp);  try_forwarding = (tmp->status == SUCCEEDED); break;
+            case try_fwd_task: internal_forward_task(tmp); break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            // edge recording
+            case add_blt_succ: internal_add_built_succ(tmp); break;
+            case del_blt_succ: internal_del_built_succ(tmp); break;
+            case add_blt_pred: internal_add_built_pred(tmp); break;
+            case del_blt_pred: internal_del_built_pred(tmp); break;
+            case blt_succ_cnt: internal_succ_cnt(tmp); break;
+            case blt_pred_cnt: internal_pred_cnt(tmp); break;
+            case blt_succ_cpy: internal_copy_succs(tmp); break;
+            case blt_pred_cpy: internal_copy_preds(tmp); break;
+#endif
             }
         }
         if (try_forwarding && !forwarder_busy) {
-            forwarder_busy = true;
-            task::enqueue(*new(task::allocate_additional_child_of(*my_parent)) internal::forward_task< buffer_node<input_type, A> >(*this));
+            task* tp = this->my_graph.root_task();
+            if(tp) {
+                forwarder_busy = true;
+                task *new_task = new(task::allocate_additional_child_of(*tp)) internal::
+                        forward_task_bypass
+                        < buffer_node<input_type, A> >(*this);
+                // tmp should point to the last item handled by the aggregator.  This is the operation
+                // the handling thread enqueued.  So modifying that record will be okay.
+                tbb::task *z = tmp->ltask;
+                tmp->ltask = combine_tasks(z, new_task);  // in case the op generated a task
+            }
         }
     }
-        
+
+    inline task *grab_forwarding_task( buffer_operation &op_data) {
+        return op_data.ltask;
+    }
+
+    inline bool enqueue_forwarding_task(buffer_operation &op_data) {
+        task *ft = grab_forwarding_task(op_data);
+        if(ft) {
+            FLOW_SPAWN(*ft);
+            return true;
+        }
+        return false;
+    }
+
     //! This is executed by an enqueued task, the "forwarder"
-    virtual void forward() {
-        buffer_operation op_data(try_fwd);
+    virtual task *forward_task() {
+        buffer_operation op_data(try_fwd_task);
+        task *last_task = NULL;
         do {
             op_data.status = WAIT;
+            op_data.ltask = NULL;
             my_aggregator.execute(&op_data);
+            tbb::task *xtask = op_data.ltask;
+            last_task = combine_tasks(last_task, xtask);
         } while (op_data.status == SUCCEEDED);
+        return last_task;
     }
-        
+
     //! Register successor
     virtual void internal_reg_succ(buffer_operation *op) {
         my_successors.register_successor(*(op->r));
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
-        
+
     //! Remove successor
     virtual void internal_rem_succ(buffer_operation *op) {
         my_successors.remove_successor(*(op->r));
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
-        
-    //! Tries to forward valid items to successors
-    virtual void internal_forward(buffer_operation *op) {
-        T i_copy;
-        bool success = false; // flagged when a successor accepts
-        size_type counter = my_successors.size();
-        // Try forwarding, giving each successor a chance
-        while (counter>0 && !this->buffer_empty() && this->item_valid(this->my_tail-1)) {
-            this->fetch_back(i_copy);
-            if( my_successors.try_put(i_copy) ) {
-                this->invalidate_back();
-                --(this->my_tail);
-                success = true; // found an accepting successor
-            }
-            --counter;
-        }
-        if (success && !counter)
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    virtual void internal_add_built_succ(buffer_operation *op) {
+        my_successors.internal_add_built_successor(*(op->r));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_del_built_succ(buffer_operation *op) {
+        my_successors.internal_delete_built_successor(*(op->r));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_add_built_pred(buffer_operation *op) {
+        my_built_predecessors.add_edge(*(op->p));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_del_built_pred(buffer_operation *op) {
+        my_built_predecessors.delete_edge(*(op->p));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_succ_cnt(buffer_operation *op) {
+        op->cnt_val = my_successors.successor_count();
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_pred_cnt(buffer_operation *op) {
+        op->cnt_val = my_built_predecessors.edge_count();
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_copy_succs(buffer_operation *op) {
+        my_successors.copy_successors(*(op->svec));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+
+    virtual void internal_copy_preds(buffer_operation *op) {
+        my_built_predecessors.copy_edges(*(op->pvec));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+    }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
+    //! Tries to forward valid items to successors
+    virtual void internal_forward_task(buffer_operation *op) {
+        if (this->my_reserved || !this->my_item_valid(this->my_tail-1)) {
+            __TBB_store_with_release(op->status, FAILED);
+            this->forwarder_busy = false;
+            return;
+        }
+        T i_copy;
+        task * last_task = NULL;
+        size_type counter = my_successors.size();
+        // Try forwarding, giving each successor a chance
+        while (counter>0 && !this->buffer_empty() && this->my_item_valid(this->my_tail-1)) {
+            this->copy_back(i_copy);
+            task *new_task = my_successors.try_put_task(i_copy);
+            if(new_task) {
+                last_task = combine_tasks(last_task, new_task);
+                this->destroy_back();
+            }
+            --counter;
+        }
+        op->ltask = last_task;  // return task
+        if (last_task && !counter) {
             __TBB_store_with_release(op->status, SUCCEEDED);
+        }
         else {
             __TBB_store_with_release(op->status, FAILED);
             forwarder_busy = false;
         }
     }
-        
+
     virtual void internal_push(buffer_operation *op) {
         this->push_back(*(op->elem));
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
-        
+
     virtual void internal_pop(buffer_operation *op) {
         if(this->pop_back(*(op->elem))) {
             __TBB_store_with_release(op->status, SUCCEEDED);
@@ -903,7 +1843,7 @@ protected:
             __TBB_store_with_release(op->status, FAILED);
         }
     }
-        
+
     virtual void internal_reserve(buffer_operation *op) {
         if(this->reserve_front(*(op->elem))) {
             __TBB_store_with_release(op->status, SUCCEEDED);
@@ -912,60 +1852,124 @@ protected:
             __TBB_store_with_release(op->status, FAILED);
         }
     }
-        
+
     virtual void internal_consume(buffer_operation *op) {
         this->consume_front();
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
-        
+
     virtual void internal_release(buffer_operation *op) {
         this->release_front();
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
-        
+
 public:
     //! Constructor
-    buffer_node( graph &g ) : reservable_item_buffer<T>(),
-        my_parent( g.root_task() ), forwarder_busy(false) {
+    buffer_node( graph &g ) : graph_node(g), internal::reservable_item_buffer<T>(),
+        forwarder_busy(false) {
         my_successors.set_owner(this);
         my_aggregator.initialize_handler(my_handler(this));
+        tbb::internal::fgt_node( tbb::internal::FLOW_BUFFER_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
     }
 
     //! Copy constructor
-    buffer_node( const buffer_node& src ) :
-        graph_node(), reservable_item_buffer<T>(), receiver<T>(), sender<T>(),
-        my_parent( src.my_parent ) {
+    buffer_node( const buffer_node& src ) : graph_node(src.my_graph),
+        internal::reservable_item_buffer<T>(), receiver<T>(), sender<T>() {
         forwarder_busy = false;
         my_successors.set_owner(this);
         my_aggregator.initialize_handler(my_handler(this));
+        tbb::internal::fgt_node( tbb::internal::FLOW_BUFFER_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<sender<output_type> *>(this) );
     }
 
     virtual ~buffer_node() {}
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
     //
     // message sender implementation
     //
-        
+
     //! Adds a new successor.
     /** Adds successor r to the list of successors; may forward tasks.  */
-    /* override */ bool register_successor( receiver<output_type> &r ) {
+    /* override */ bool register_successor( successor_type &r ) {
         buffer_operation op_data(reg_succ);
         op_data.r = &r;
         my_aggregator.execute(&op_data);
+        (void)enqueue_forwarding_task(op_data);
         return true;
     }
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    /*override*/ void internal_add_built_successor( successor_type &r) {
+        buffer_operation op_data(add_blt_succ);
+        op_data.r = &r;
+        my_aggregator.execute(&op_data);
+    }
+
+    /*override*/ void internal_delete_built_successor( successor_type &r) {
+        buffer_operation op_data(del_blt_succ);
+        op_data.r = &r;
+        my_aggregator.execute(&op_data);
+    }
+
+    /*override*/ void internal_add_built_predecessor( predecessor_type &p) {
+        buffer_operation op_data(add_blt_pred);
+        op_data.p = &p;
+        my_aggregator.execute(&op_data);
+    }
+
+    /*override*/ void internal_delete_built_predecessor( predecessor_type &p) {
+        buffer_operation op_data(del_blt_pred);
+        op_data.p = &p;
+        my_aggregator.execute(&op_data);
+    }
+
+    /*override*/ size_t predecessor_count() {
+        buffer_operation op_data(blt_pred_cnt);
+        my_aggregator.execute(&op_data);
+        return op_data.cnt_val;
+    }
+
+    /*override*/ size_t successor_count() {
+        buffer_operation op_data(blt_succ_cnt);
+        my_aggregator.execute(&op_data);
+        return op_data.cnt_val;
+    }
+
+    /*override*/ void copy_predecessors( predecessor_vector_type &v ) {
+        buffer_operation op_data(blt_pred_cpy);
+        op_data.pvec = &v;
+        my_aggregator.execute(&op_data);
+    }
+
+    /*override*/ void copy_successors( successor_vector_type &v ) {
+        buffer_operation op_data(blt_succ_cpy);
+        op_data.svec = &v;
+        my_aggregator.execute(&op_data);
+    }
+#endif
+
     //! Removes a successor.
     /** Removes successor r from the list of successors.
         It also calls r.remove_predecessor(*this) to remove this node as a predecessor. */
-    /* override */ bool remove_successor( receiver<output_type> &r ) {
+    /* override */ bool remove_successor( successor_type &r ) {
         r.remove_predecessor(*this);
         buffer_operation op_data(rem_succ);
         op_data.r = &r;
         my_aggregator.execute(&op_data);
+        // even though this operation does not cause a forward, if we are the handler, and
+        // a forward is scheduled, we may be the first to reach this point after the aggregator,
+        // and so should check for the task.
+        (void)enqueue_forwarding_task(op_data);
         return true;
     }
-        
+
     //! Request an item from the buffer_node
     /**  true = v contains the returned item<BR>
          false = no item has been returned */
@@ -973,9 +1977,10 @@ public:
         buffer_operation op_data(req_item);
         op_data.elem = &v;
         my_aggregator.execute(&op_data);
+        (void)enqueue_forwarding_task(op_data);
         return (op_data.status==SUCCEEDED);
     }
-        
+
     //! Reserves an item.
     /**  false = no item can be reserved<BR>
          true = an item is reserved */
@@ -983,74 +1988,108 @@ public:
         buffer_operation op_data(res_item);
         op_data.elem = &v;
         my_aggregator.execute(&op_data);
+        (void)enqueue_forwarding_task(op_data);
         return (op_data.status==SUCCEEDED);
     }
-        
+
     //! Release a reserved item.
     /**  true = item has been released and so remains in sender */
     /* override */ bool try_release() {
         buffer_operation op_data(rel_res);
         my_aggregator.execute(&op_data);
+        (void)enqueue_forwarding_task(op_data);
         return true;
     }
-        
+
     //! Consumes a reserved item.
     /** true = item is removed from sender and reservation removed */
     /* override */ bool try_consume() {
         buffer_operation op_data(con_res);
         my_aggregator.execute(&op_data);
+        (void)enqueue_forwarding_task(op_data);
         return true;
     }
-        
-    //! Receive an item
-    /** true is always returned */
-    /* override */ bool try_put(const T &t) {
+
+protected:
+
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    //! receive an item, return a task *if possible
+    /* override */ task *try_put_task(const T &t) {
         buffer_operation op_data(t, put_item);
         my_aggregator.execute(&op_data);
-        return true;
+        task *ft = grab_forwarding_task(op_data);
+        // sequencer_nodes can return failure (if an item has been previously inserted)
+        // We have to spawn the returned task if our own operation fails.
+
+        if(ft && op_data.status == FAILED) {
+            // we haven't succeeded queueing the item, but for some reason the
+            // call returned a task (if another request resulted in a successful
+            // forward this could happen.)  Queue the task and reset the pointer.
+            FLOW_SPAWN(*ft); ft = NULL;
+        }
+        else if(!ft && op_data.status == SUCCEEDED) {
+            ft = SUCCESSFULLY_ENQUEUED;
+        }
+        return ft;
     }
-};
-        
-        
+
+    /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        internal::reservable_item_buffer<T, A>::reset();
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_successors.reset(f);
+        if (f&rf_extract) {
+            my_built_predecessors.receiver_extract(*this);
+        }
+#endif
+        forwarder_busy = false;
+    }
+
+    /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { }
+
+};  // buffer_node
+
 //! Forwards messages in FIFO order
 template <typename T, typename A=cache_aligned_allocator<T> >
 class queue_node : public buffer_node<T, A> {
 protected:
-typedef typename buffer_node<T, A>::size_type size_type;
-typedef typename buffer_node<T, A>::buffer_operation queue_operation;
-        
+    typedef buffer_node<T, A> base_type;
+    typedef typename base_type::size_type size_type;
+    typedef typename base_type::buffer_operation queue_operation;
+
     enum op_stat {WAIT=0, SUCCEEDED, FAILED};
-        
-    //! Tries to forward valid items to successors
-    /* override */ void internal_forward(queue_operation *op) {
-        T i_copy;
-        bool success = false; // flagged when a successor accepts
-        size_type counter = this->my_successors.size();
-        if (this->my_reserved || !this->item_valid(this->my_head)){
+
+    /* override */ void internal_forward_task(queue_operation *op) {
+        if (this->my_reserved || !this->my_item_valid(this->my_head)) {
             __TBB_store_with_release(op->status, FAILED);
             this->forwarder_busy = false;
             return;
         }
+        T i_copy;
+        task *last_task = NULL;
+        size_type counter = this->my_successors.size();
         // Keep trying to send items while there is at least one accepting successor
-        while (counter>0 && this->item_valid(this->my_head)) {
-            this->fetch_front(i_copy);
-            if(this->my_successors.try_put(i_copy)) {
-                 this->invalidate_front();
-                 ++(this->my_head);
-                success = true; // found an accepting successor
+        while (counter>0 && this->my_item_valid(this->my_head)) {
+            this->copy_front(i_copy);
+            task *new_task = this->my_successors.try_put_task(i_copy);
+            if(new_task) {
+                this->destroy_front();
+                last_task = combine_tasks(last_task, new_task);
             }
             --counter;
         }
-        if (success && !counter)
+        op->ltask = last_task;
+        if (last_task && !counter)
             __TBB_store_with_release(op->status, SUCCEEDED);
         else {
             __TBB_store_with_release(op->status, FAILED);
             this->forwarder_busy = false;
         }
     }
-        
+
     /* override */ void internal_pop(queue_operation *op) {
-        if ( this->my_reserved || !this->item_valid(this->my_head)){
+        if ( this->my_reserved || !this->my_item_valid(this->my_head)){
             __TBB_store_with_release(op->status, FAILED);
         }
         else {
@@ -1059,13 +2098,11 @@ typedef typename buffer_node<T, A>::buffer_operation queue_operation;
         }
     }
     /* override */ void internal_reserve(queue_operation *op) {
-        if (this->my_reserved || !this->item_valid(this->my_head)) {
+        if (this->my_reserved || !this->my_item_valid(this->my_head)) {
             __TBB_store_with_release(op->status, FAILED);
         }
         else {
-            this->my_reserved = true;
-            this->fetch_front(*(op->elem));
-            this->invalidate_front();
+            this->reserve_front(*(op->elem));
             __TBB_store_with_release(op->status, SUCCEEDED);
         }
     }
@@ -1073,86 +2110,155 @@ typedef typename buffer_node<T, A>::buffer_operation queue_operation;
         this->consume_front();
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
-        
+
 public:
-        
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
+
     //! Constructor
-    queue_node( graph &g ) : buffer_node<T, A>(g) {}
+    queue_node( graph &g ) : base_type(g) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
 
     //! Copy constructor
-    queue_node( const queue_node& src) : buffer_node<T, A>(src) {}
-};
-        
+    queue_node( const queue_node& src) : base_type(src) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_QUEUE_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
+    /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        base_type::reset(__TBB_PFG_RESET_ARG(f));
+    }
+};  // queue_node
+
 //! Forwards messages in sequence order
 template< typename T, typename A=cache_aligned_allocator<T> >
 class sequencer_node : public queue_node<T, A> {
     internal::function_body< T, size_t > *my_sequencer;
+    // my_sequencer should be a benign function and must be callable
+    // from a parallel context.  Does this mean it needn't be reset?
 public:
-        
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
+
     //! Constructor
     template< typename Sequencer >
     sequencer_node( graph &g, const Sequencer& s ) : queue_node<T, A>(g),
-        my_sequencer(new internal::function_body_leaf< T, size_t, Sequencer>(s) ) {}
+        my_sequencer(new internal::function_body_leaf< T, size_t, Sequencer>(s) ) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
 
     //! Copy constructor
     sequencer_node( const sequencer_node& src ) : queue_node<T, A>(src),
-        my_sequencer( src.my_sequencer->clone() ) {}
-        
+        my_sequencer( src.my_sequencer->clone() ) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_SEQUENCER_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
+
     //! Destructor
     ~sequencer_node() { delete my_sequencer; }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
 protected:
     typedef typename buffer_node<T, A>::size_type size_type;
     typedef typename buffer_node<T, A>::buffer_operation sequencer_operation;
-        
+
     enum op_stat {WAIT=0, SUCCEEDED, FAILED};
-        
+
 private:
     /* override */ void internal_push(sequencer_operation *op) {
         size_type tag = (*my_sequencer)(*(op->elem));
-        
-        this->my_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail;
-        
-        if(this->size() > this->capacity())
-            this->grow_my_array(this->size());  // tail already has 1 added to it
-        this->item(tag) = std::make_pair( *(op->elem), true );
-        __TBB_store_with_release(op->status, SUCCEEDED);
+#if !TBB_DEPRECATED_SEQUENCER_DUPLICATES
+        if(tag < this->my_head) {
+            // have already emitted a message with this tag
+            __TBB_store_with_release(op->status, FAILED);
+            return;
+        }
+#endif
+        // cannot modify this->my_tail now; the buffer would be inconsistent.
+        size_t new_tail = (tag+1 > this->my_tail) ? tag+1 : this->my_tail;
+
+        if(this->size(new_tail) > this->capacity()) {
+            this->grow_my_array(this->size(new_tail));
+        }
+        this->my_tail = new_tail;
+        if(this->place_item(tag,*(op->elem))) {
+            __TBB_store_with_release(op->status, SUCCEEDED);
+        }
+        else {
+            // already have a message with this tag
+            __TBB_store_with_release(op->status, FAILED);
+        }
     }
-};
-        
+};  // sequencer_node
+
 //! Forwards messages in priority order
 template< typename T, typename Compare = std::less<T>, typename A=cache_aligned_allocator<T> >
 class priority_queue_node : public buffer_node<T, A> {
 public:
     typedef T input_type;
     typedef T output_type;
+    typedef buffer_node<T,A> base_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
+
     //! Constructor
-    priority_queue_node( graph &g ) : buffer_node<T, A>(g), mark(0) {}
+    priority_queue_node( graph &g ) : buffer_node<T, A>(g), mark(0) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
 
     //! Copy constructor
-    priority_queue_node( const priority_queue_node &src ) : buffer_node<T, A>(src), mark(0) {}
-        
+    priority_queue_node( const priority_queue_node &src ) : buffer_node<T, A>(src), mark(0) {
+        tbb::internal::fgt_node( tbb::internal::FLOW_PRIORITY_QUEUE_NODE, &(this->my_graph),
+                                 static_cast<receiver<input_type> *>(this),
+                                 static_cast<sender<output_type> *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
+
 protected:
+
+    /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        mark = 0;
+        base_type::reset(__TBB_PFG_RESET_ARG(f));
+    }
+
     typedef typename buffer_node<T, A>::size_type size_type;
     typedef typename buffer_node<T, A>::item_type item_type;
     typedef typename buffer_node<T, A>::buffer_operation prio_operation;
-        
+
     enum op_stat {WAIT=0, SUCCEEDED, FAILED};
-        
+
     /* override */ void handle_operations(prio_operation *op_list) {
-        prio_operation *tmp /*, *pop_list*/ ;
+        prio_operation *tmp = op_list /*, *pop_list*/ ;
         bool try_forwarding=false;
         while (op_list) {
             tmp = op_list;
@@ -1161,27 +2267,49 @@ protected:
             case buffer_node<T, A>::reg_succ: this->internal_reg_succ(tmp); try_forwarding = true; break;
             case buffer_node<T, A>::rem_succ: this->internal_rem_succ(tmp); break;
             case buffer_node<T, A>::put_item: internal_push(tmp); try_forwarding = true; break;
-            case buffer_node<T, A>::try_fwd: internal_forward(tmp); break;
+            case buffer_node<T, A>::try_fwd_task: internal_forward_task(tmp); break;
             case buffer_node<T, A>::rel_res: internal_release(tmp); try_forwarding = true; break;
             case buffer_node<T, A>::con_res: internal_consume(tmp); try_forwarding = true; break;
             case buffer_node<T, A>::req_item: internal_pop(tmp); break;
             case buffer_node<T, A>::res_item: internal_reserve(tmp); break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            case buffer_node<T, A>::add_blt_succ: this->internal_add_built_succ(tmp); break;
+            case buffer_node<T, A>::del_blt_succ: this->internal_del_built_succ(tmp); break;
+            case buffer_node<T, A>::add_blt_pred: this->internal_add_built_pred(tmp); break;
+            case buffer_node<T, A>::del_blt_pred: this->internal_del_built_pred(tmp); break;
+            case buffer_node<T, A>::blt_succ_cnt: this->internal_succ_cnt(tmp); break;
+            case buffer_node<T, A>::blt_pred_cnt: this->internal_pred_cnt(tmp); break;
+            case buffer_node<T, A>::blt_succ_cpy: this->internal_copy_succs(tmp); break;
+            case buffer_node<T, A>::blt_pred_cpy: this->internal_copy_preds(tmp); break;
+#endif
             }
         }
         // process pops!  for now, no special pop processing
+        // concurrent_priority_queue handles pushes first, then pops.
+        // that is the genesis of this comment
         if (mark<this->my_tail) heapify();
-        if (try_forwarding && !this->forwarder_busy) {
-            this->forwarder_busy = true;
-            task::enqueue(*new(task::allocate_additional_child_of(*(this->my_parent))) internal::forward_task< buffer_node<input_type, A> >(*this));
+        __TBB_ASSERT(mark == this->my_tail, "mark unequal after heapify");
+        if (try_forwarding && !this->forwarder_busy) {  // could we also test for this->my_tail (queue non-empty)?
+            task* tp = this->my_graph.root_task();
+            if(tp) {
+                this->forwarder_busy = true;
+                task *new_task = new(task::allocate_additional_child_of(*tp)) internal::
+                        forward_task_bypass
+                        < buffer_node<input_type, A> >(*this);
+                // tmp should point to the last item handled by the aggregator.  This is the operation
+                // the handling thread enqueued.  So modifying that record will be okay.
+                tbb::task *tmp1 = tmp->ltask;
+                tmp->ltask = combine_tasks(tmp1, new_task);
+            }
         }
     }
-        
+
     //! Tries to forward valid items to successors
-    /* override */ void internal_forward(prio_operation *op) {
+    /* override */ void internal_forward_task(prio_operation *op) {
         T i_copy;
-        bool success = false; // flagged when a successor accepts
+        task * last_task = NULL; // flagged when a successor accepts
         size_type counter = this->my_successors.size();
-        
+
         if (this->my_reserved || this->my_tail == 0) {
             __TBB_store_with_release(op->status, FAILED);
             this->forwarder_busy = false;
@@ -1189,214 +2317,324 @@ protected:
         }
         // Keep trying to send while there exists an accepting successor
         while (counter>0 && this->my_tail > 0) {
-            i_copy = this->my_array[0].first;
-            bool msg = this->my_successors.try_put(i_copy);
-            if ( msg == true ) {
-                 if (mark == this->my_tail) --mark;
-                --(this->my_tail);
-                this->my_array[0].first=this->my_array[this->my_tail].first;
-                if (this->my_tail > 1) // don't reheap for heap of size 1
-                    reheap();
-                success = true; // found an accepting successor
+            prio_copy(i_copy);
+            task * new_task = this->my_successors.try_put_task(i_copy);
+            if ( new_task ) {
+                last_task = combine_tasks(last_task, new_task);
+                prio_pop();
             }
             --counter;
         }
-        if (success && !counter)
+        op->ltask = last_task;
+        if (last_task && !counter)
             __TBB_store_with_release(op->status, SUCCEEDED);
         else {
             __TBB_store_with_release(op->status, FAILED);
             this->forwarder_busy = false;
         }
     }
-        
+
     /* override */ void internal_push(prio_operation *op) {
-        if ( this->my_tail >= this->my_array_size )
-            this->grow_my_array( this->my_tail + 1 );
-        this->my_array[this->my_tail] = std::make_pair( *(op->elem), true );
-        ++(this->my_tail);
+        prio_push(*(op->elem));
         __TBB_store_with_release(op->status, SUCCEEDED);
     }
+
     /* override */ void internal_pop(prio_operation *op) {
+        // if empty or already reserved, don't pop
         if ( this->my_reserved == true || this->my_tail == 0 ) {
             __TBB_store_with_release(op->status, FAILED);
+            return;
         }
-        else {
-            if (mark<this->my_tail &&
-                compare(this->my_array[0].first,
-                        this->my_array[this->my_tail-1].first)) {
-                // there are newly pushed elems; last one higher than top
-                // copy the data
-                *(op->elem) = this->my_array[this->my_tail-1].first;
-                --(this->my_tail);
-                __TBB_store_with_release(op->status, SUCCEEDED);
-            }
-            else { // extract and push the last element down heap
-                *(op->elem) = this->my_array[0].first; // copy the data
-                if (mark == this->my_tail) --mark;
-                --(this->my_tail);
-                __TBB_store_with_release(op->status, SUCCEEDED);
-                this->my_array[0].first=this->my_array[this->my_tail].first;
-                if (this->my_tail > 1) // don't reheap for heap of size 1
-                    reheap();
-            }
-        }
+
+        prio_copy(*(op->elem));
+        __TBB_store_with_release(op->status, SUCCEEDED);
+        prio_pop();
+
     }
+
+    // pops the highest-priority item, saves copy
     /* override */ void internal_reserve(prio_operation *op) {
         if (this->my_reserved == true || this->my_tail == 0) {
             __TBB_store_with_release(op->status, FAILED);
+            return;
         }
-        else {
-            this->my_reserved = true;
-            *(op->elem) = reserved_item = this->my_array[0].first;
-            if (mark == this->my_tail) --mark;
-            --(this->my_tail);
-            __TBB_store_with_release(op->status, SUCCEEDED);
-            this->my_array[0].first = this->my_array[this->my_tail].first;
-            if (this->my_tail > 1) // don't reheap for heap of size 1
-                reheap();
-        }
+        this->my_reserved = true;
+        prio_copy(*(op->elem));
+        reserved_item = *(op->elem);
+        __TBB_store_with_release(op->status, SUCCEEDED);
+        prio_pop();
     }
+
     /* override */ void internal_consume(prio_operation *op) {
-        this->my_reserved = false;
         __TBB_store_with_release(op->status, SUCCEEDED);
+        this->my_reserved = false;
+        reserved_item = input_type();
     }
+
     /* override */ void internal_release(prio_operation *op) {
-        if (this->my_tail >= this->my_array_size)
-            this->grow_my_array( this->my_tail + 1 );
-        this->my_array[this->my_tail] = std::make_pair(reserved_item, true);
-        ++(this->my_tail);
-        this->my_reserved = false;
         __TBB_store_with_release(op->status, SUCCEEDED);
-        heapify();
+        prio_push(reserved_item);
+        this->my_reserved = false;
+        reserved_item = input_type();
     }
 private:
     Compare compare;
     size_type mark;
+
     input_type reserved_item;
-        
+
+    // in case a reheap has not been done after a push, check if the mark item is higher than the 0'th item
+    bool prio_use_tail() {
+        __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds before test");
+        return mark < this->my_tail && compare(this->get_my_item(0), this->get_my_item(this->my_tail - 1));
+    }
+
+    // prio_push: checks that the item will fit, expand array if necessary, put at end
+    void prio_push(const T &src) {
+        if ( this->my_tail >= this->my_array_size )
+            this->grow_my_array( this->my_tail + 1 );
+        (void) this->place_item(this->my_tail, src);
+        ++(this->my_tail);
+        __TBB_ASSERT(mark < this->my_tail, "mark outside bounds after push");
+    }
+
+    // prio_pop: deletes highest priority item from the array, and if it is item
+    // 0, move last item to 0 and reheap.  If end of array, just destroy and decrement tail
+    // and mark.  Assumes the array has already been tested for emptiness; no failure.
+    void prio_pop()  {
+        if (prio_use_tail()) {
+            // there are newly pushed elems; last one higher than top
+            // copy the data
+            this->destroy_item(this->my_tail-1);
+            --(this->my_tail);
+            __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop");
+            return;
+        }
+        this->destroy_item(0);
+        if(this->my_tail > 1) {
+            // push the last element down heap
+            __TBB_ASSERT(this->my_item_valid(this->my_tail - 1), NULL);
+            this->move_item(0,this->my_tail - 1);
+        }
+        --(this->my_tail);
+        if(mark > this->my_tail) --mark;
+        if (this->my_tail > 1) // don't reheap for heap of size 1
+            reheap();
+        __TBB_ASSERT(mark <= this->my_tail, "mark outside bounds after pop");
+    }
+
+    void prio_copy(T &res) {
+        if (prio_use_tail()) {
+            res = this->get_my_item(this->my_tail - 1);
+        }
+        else {
+            res = this->get_my_item(0);
+        }
+    }
+
+    // turn array into heap
     void heapify() {
+        if(this->my_tail == 0) {
+            mark = 0;
+            return;
+        }
         if (!mark) mark = 1;
         for (; mark<this->my_tail; ++mark) { // for each unheaped element
             size_type cur_pos = mark;
-            input_type to_place = this->my_array[mark].first;
+            input_type to_place;
+            this->fetch_item(mark,to_place);
             do { // push to_place up the heap
                 size_type parent = (cur_pos-1)>>1;
-                if (!compare(this->my_array[parent].first, to_place))
+                if (!compare(this->get_my_item(parent), to_place))
                     break;
-                this->my_array[cur_pos].first = this->my_array[parent].first;
+                this->move_item(cur_pos, parent);
                 cur_pos = parent;
             } while( cur_pos );
-            this->my_array[cur_pos].first = to_place;
+            (void) this->place_item(cur_pos, to_place);
         }
     }
-        
+
+    // otherwise heapified array with new root element; rearrange to heap
     void reheap() {
         size_type cur_pos=0, child=1;
         while (child < mark) {
             size_type target = child;
             if (child+1<mark &&
-                compare(this->my_array[child].first,
-                        this->my_array[child+1].first))
+                compare(this->get_my_item(child),
+                        this->get_my_item(child+1)))
                 ++target;
             // target now has the higher priority child
-            if (compare(this->my_array[target].first,
-                        this->my_array[this->my_tail].first))
+            if (compare(this->get_my_item(target),
+                        this->get_my_item(cur_pos)))
                 break;
-            this->my_array[cur_pos].first = this->my_array[target].first;
+            // swap
+            this->swap_items(cur_pos, target);
             cur_pos = target;
             child = (cur_pos<<1)+1;
         }
-        this->my_array[cur_pos].first = this->my_array[this->my_tail].first;
     }
-};
-        
+};  // priority_queue_node
+
 //! Forwards messages only if the threshold has not been reached
 /** This node forwards items until its threshold is reached.
     It contains no buffering.  If the downstream node rejects, the
     message is dropped. */
 template< typename T >
 class limiter_node : public graph_node, public receiver< T >, public sender< T > {
+protected:
+    using graph_node::my_graph;
 public:
-        
     typedef T input_type;
     typedef T output_type;
     typedef sender< input_type > predecessor_type;
     typedef receiver< output_type > successor_type;
-        
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    typedef std::vector<successor_type *> successor_vector_type;
+    typedef std::vector<predecessor_type *> predecessor_vector_type;
+#endif
+
 private:
-        
-    task *my_root_task;
     size_t my_threshold;
-    size_t my_count;
-    internal::predecessor_cache< T > my_predecessors;
+    size_t my_count; //number of successful puts
+    size_t my_tries; //number of active put attempts
+    internal::reservable_predecessor_cache< T, spin_mutex > my_predecessors;
     spin_mutex my_mutex;
     internal::broadcast_cache< T > my_successors;
     int init_decrement_predecessors;
 
-    friend class internal::forward_task< limiter_node<T> >;
-        
+    friend class internal::forward_task_bypass< limiter_node<T> >;
+
     // Let decrementer call decrement_counter()
     friend class internal::decrementer< limiter_node<T> >;
-        
-    void decrement_counter() {
+
+    bool check_conditions() {  // always called under lock
+        return ( my_count + my_tries < my_threshold && !my_predecessors.empty() && !my_successors.empty() );
+    }
+
+    // only returns a valid task pointer or NULL, never SUCCESSFULLY_ENQUEUED
+    task *forward_task() {
         input_type v;
-        
-        // If we can't get / put an item immediately then drop the count
-        if ( my_predecessors.get_item( v ) == false 
-             || my_successors.try_put(v) == false ) {
+        task *rval = NULL;
+        bool reserved = false;
+            {
+                spin_mutex::scoped_lock lock(my_mutex);
+                if ( check_conditions() )
+                    ++my_tries;
+                else
+                    return NULL;
+            }
+
+        //SUCCESS 
+        // if we can reserve and can put, we consume the reservation 
+        // we increment the count and decrement the tries
+        if ( (my_predecessors.try_reserve(v)) == true ){
+            reserved=true;
+            if ( (rval = my_successors.try_put_task(v)) != NULL ){
+                {
+                    spin_mutex::scoped_lock lock(my_mutex);
+                    ++my_count;
+                    --my_tries;
+                    my_predecessors.try_consume();
+                    if ( check_conditions() ) {
+                        task* tp = this->my_graph.root_task();
+                        if ( tp ) {
+                            task *rtask = new ( task::allocate_additional_child_of( *tp ) )
+                                internal::forward_task_bypass< limiter_node<T> >( *this );
+                            FLOW_SPAWN (*rtask);
+                        }
+                    }
+                }
+                return rval;
+            }
+        }
+        //FAILURE
+        //if we can't reserve, we decrement the tries
+        //if we can reserve but can't put, we decrement the tries and release the reservation
+        {
             spin_mutex::scoped_lock lock(my_mutex);
-            --my_count;
-            if ( !my_predecessors.empty() ) 
-                task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-                            internal::forward_task< limiter_node<T> >( *this ) );
+            --my_tries;
+            if (reserved) my_predecessors.try_release();
+            if ( check_conditions() ) {
+                task* tp = this->my_graph.root_task();
+                if ( tp ) {
+                    task *rtask = new ( task::allocate_additional_child_of( *tp ) )
+                        internal::forward_task_bypass< limiter_node<T> >( *this );
+                    __TBB_ASSERT(!rval, "Have two tasks to handle");
+                    return rtask;
+                }
+            }
+            return rval;
         }
     }
-        
+
     void forward() {
+        __TBB_ASSERT(false, "Should never be called");
+        return;
+    }
+
+    task * decrement_counter() {
         {
             spin_mutex::scoped_lock lock(my_mutex);
-            if ( my_count < my_threshold ) 
-                ++my_count;
-            else
-                return;
+            if(my_count) --my_count;
         }
-        decrement_counter();
+        return forward_task();
     }
-        
+
 public:
-        
     //! The internal receiver< continue_msg > that decrements the count
     internal::decrementer< limiter_node<T> > decrement;
-        
+
     //! Constructor
-    limiter_node(graph &g, size_t threshold, int num_decrement_predecessors=0) : 
-        my_root_task(g.root_task()), my_threshold(threshold), my_count(0), 
-        init_decrement_predecessors(num_decrement_predecessors), 
-        decrement(num_decrement_predecessors) 
+    limiter_node(graph &g, size_t threshold, int num_decrement_predecessors=0) :
+        graph_node(g), my_threshold(threshold), my_count(0), my_tries(0),
+        init_decrement_predecessors(num_decrement_predecessors),
+        decrement(num_decrement_predecessors)
     {
         my_predecessors.set_owner(this);
         my_successors.set_owner(this);
         decrement.set_owner(this);
+        tbb::internal::fgt_node( tbb::internal::FLOW_LIMITER_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<receiver<continue_msg> *>(&decrement),
+                                 static_cast<sender<output_type> *>(this) );
     }
-        
+
     //! Copy constructor
-    limiter_node( const limiter_node& src ) : 
-        graph_node(), receiver<T>(), sender<T>(),
-        my_root_task(src.my_root_task), my_threshold(src.my_threshold), my_count(0), 
-        init_decrement_predecessors(src.init_decrement_predecessors), 
-        decrement(src.init_decrement_predecessors) 
+    limiter_node( const limiter_node& src ) :
+        graph_node(src.my_graph), receiver<T>(), sender<T>(),
+        my_threshold(src.my_threshold), my_count(0), my_tries(0),
+        init_decrement_predecessors(src.init_decrement_predecessors),
+        decrement(src.init_decrement_predecessors)
     {
         my_predecessors.set_owner(this);
         my_successors.set_owner(this);
         decrement.set_owner(this);
+        tbb::internal::fgt_node( tbb::internal::FLOW_LIMITER_NODE, &this->my_graph,
+                                 static_cast<receiver<input_type> *>(this), static_cast<receiver<continue_msg> *>(&decrement),
+                                 static_cast<sender<output_type> *>(this) );
     }
 
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
     //! Replace the current successor with this new successor
     /* override */ bool register_successor( receiver<output_type> &r ) {
+        spin_mutex::scoped_lock lock(my_mutex);
+        bool was_empty = my_successors.empty();
         my_successors.register_successor(r);
+        //spawn a forward task if this is the only successor
+        if ( was_empty && !my_predecessors.empty() && my_count + my_tries < my_threshold ) {
+            task* tp = this->my_graph.root_task();
+            if ( tp ) {
+                FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *tp ) )
+                            internal::forward_task_bypass < limiter_node<T> >( *this ) ) );
+            }
+        }
         return true;
     }
-        
+
     //! Removes a successor from this node
     /** r.remove_predecessor(*this) is also called. */
     /* override */ bool remove_successor( receiver<output_type> &r ) {
@@ -1404,47 +2642,100 @@ public:
         my_successors.remove_successor(r);
         return true;
     }
-        
-    //! Puts an item to this receiver
-    /* override */ bool try_put( const T &t ) {
-        {
-            spin_mutex::scoped_lock lock(my_mutex);
-            if ( my_count >= my_threshold ) 
-                return false;
-            else
-                ++my_count; 
-        }
-        
-        bool msg = my_successors.try_put(t);
-        
-        if ( msg != true ) {
-            spin_mutex::scoped_lock lock(my_mutex);
-            --my_count;
-            if ( !my_predecessors.empty() ) 
-                task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-                            internal::forward_task< limiter_node<T> >( *this ) );
-        }
-        
-        return msg;
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    /*override*/void internal_add_built_successor(receiver<output_type> &src) {
+        my_successors.internal_add_built_successor(src);
     }
-        
-    //! Removes src from the list of cached predecessors.
+
+    /*override*/void internal_delete_built_successor(receiver<output_type> &src) {
+        my_successors.internal_delete_built_successor(src);
+    }
+
+    /*override*/size_t successor_count() { return my_successors.successor_count(); }
+
+    /*override*/ void copy_successors(successor_vector_type &v) {
+        my_successors.copy_successors(v);
+    }
+
+    /*override*/void internal_add_built_predecessor(sender<output_type> &src) {
+        my_predecessors.internal_add_built_predecessor(src);
+    }
+
+    /*override*/void internal_delete_built_predecessor(sender<output_type> &src) {
+        my_predecessors.internal_delete_built_predecessor(src);
+    }
+
+    /*override*/size_t predecessor_count() { return my_predecessors.predecessor_count(); }
+
+    /*override*/ void copy_predecessors(predecessor_vector_type &v) {
+        my_predecessors.copy_predecessors(v);
+    }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
+    //! Adds src to the list of cached predecessors.
     /* override */ bool register_predecessor( predecessor_type &src ) {
         spin_mutex::scoped_lock lock(my_mutex);
         my_predecessors.add( src );
-        if ( my_count < my_threshold && !my_successors.empty() ) 
-            task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-                           internal::forward_task< limiter_node<T> >( *this ) );
+        task* tp = this->my_graph.root_task();
+        if ( my_count + my_tries < my_threshold && !my_successors.empty() && tp ) {
+            FLOW_SPAWN( (* new ( task::allocate_additional_child_of( *tp ) )
+                        internal::forward_task_bypass < limiter_node<T> >( *this ) ) );
+        }
         return true;
     }
-        
+
     //! Removes src from the list of cached predecessors.
     /* override */ bool remove_predecessor( predecessor_type &src ) {
         my_predecessors.remove( src );
         return true;
     }
-        
-};
+
+protected:
+
+    template< typename R, typename B > friend class run_and_put_task;
+    template<typename X, typename Y> friend class internal::broadcast_cache;
+    template<typename X, typename Y> friend class internal::round_robin_cache;
+    //! Puts an item to this receiver
+    /* override */ task *try_put_task( const T &t ) {
+        {
+            spin_mutex::scoped_lock lock(my_mutex);
+            if ( my_count + my_tries >= my_threshold )
+                return NULL;
+            else
+                ++my_tries;
+        }
+
+        task * rtask = my_successors.try_put_task(t);
+
+        if ( !rtask ) {  // try_put_task failed.
+            spin_mutex::scoped_lock lock(my_mutex);
+            --my_tries;
+            task* tp = this->my_graph.root_task();
+            if ( check_conditions() && tp ) {
+                rtask = new ( task::allocate_additional_child_of( *tp ) )
+                    internal::forward_task_bypass< limiter_node<T> >( *this );
+            }
+        }
+        else {
+            spin_mutex::scoped_lock lock(my_mutex);
+            ++my_count;
+            --my_tries;
+             }
+        return rtask;
+    }
+
+    /*override*/void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+        my_count = 0;
+        my_predecessors.reset(__TBB_PFG_RESET_ARG(f));
+        decrement.reset_receiver(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        my_successors.reset(f);
+#endif
+    }
+
+    /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { my_predecessors.reset(__TBB_PFG_RESET_ARG(f)); }
+};  // limiter_node
 
 #include "internal/_flow_graph_join_impl.h"
 
@@ -1458,132 +2749,515 @@ using internal::NO_TAG;
 template<typename OutputTuple, graph_buffer_policy JP=queueing> class join_node;
 
 template<typename OutputTuple>
-class join_node<OutputTuple,reserving>: public internal::unfolded_join_node<std::tuple_size<OutputTuple>::value, reserving_port, OutputTuple, reserving> {
+class join_node<OutputTuple,reserving>: public internal::unfolded_join_node<tbb::flow::tuple_size<OutputTuple>::value, reserving_port, OutputTuple, reserving> {
 private:
-    static const int N = std::tuple_size<OutputTuple>::value;
+    static const int N = tbb::flow::tuple_size<OutputTuple>::value;
     typedef typename internal::unfolded_join_node<N, reserving_port, OutputTuple, reserving> unfolded_type;
 public:
     typedef OutputTuple output_type;
-    typedef typename unfolded_type::input_ports_tuple_type input_ports_tuple_type;
-    join_node(graph &g) : unfolded_type(g) { }
-    join_node(const join_node &other) : unfolded_type(other) {}
+    typedef typename unfolded_type::input_ports_type input_ports_type;
+    join_node(graph &g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
+                                            this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    join_node(const join_node &other) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_RESERVING, &this->my_graph,
+                                            this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
 };
 
 template<typename OutputTuple>
-class join_node<OutputTuple,queueing>: public internal::unfolded_join_node<std::tuple_size<OutputTuple>::value, queueing_port, OutputTuple, queueing> {
+class join_node<OutputTuple,queueing>: public internal::unfolded_join_node<tbb::flow::tuple_size<OutputTuple>::value, queueing_port, OutputTuple, queueing> {
 private:
-    static const int N = std::tuple_size<OutputTuple>::value;
+    static const int N = tbb::flow::tuple_size<OutputTuple>::value;
     typedef typename internal::unfolded_join_node<N, queueing_port, OutputTuple, queueing> unfolded_type;
 public:
     typedef OutputTuple output_type;
-    typedef typename unfolded_type::input_ports_tuple_type input_ports_tuple_type;
-    join_node(graph &g) : unfolded_type(g) { }
-    join_node(const join_node &other) : unfolded_type(other) {}
+    typedef typename unfolded_type::input_ports_type input_ports_type;
+    join_node(graph &g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
+                                            this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    join_node(const join_node &other) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_QUEUEING, &this->my_graph,
+                                            this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
 };
 
 // template for tag_matching join_node
 template<typename OutputTuple>
-class join_node<OutputTuple, tag_matching> : public internal::unfolded_join_node<std::tuple_size<OutputTuple>::value,
+class join_node<OutputTuple, tag_matching> : public internal::unfolded_join_node<tbb::flow::tuple_size<OutputTuple>::value,
       tag_matching_port, OutputTuple, tag_matching> {
 private:
-    static const int N = std::tuple_size<OutputTuple>::value;
+    static const int N = tbb::flow::tuple_size<OutputTuple>::value;
     typedef typename internal::unfolded_join_node<N, tag_matching_port, OutputTuple, tag_matching> unfolded_type;
 public:
     typedef OutputTuple output_type;
-    typedef typename unfolded_type::input_ports_tuple_type input_ports_tuple_type;
-    template<typename B0, typename B1>
-    join_node(graph &g, B0 b0, B1 b1) : unfolded_type(g, b0, b1) { }
-    template<typename B0, typename B1, typename B2>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2) : unfolded_type(g, b0, b1, b2) { }
-    template<typename B0, typename B1, typename B2, typename B3>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3) : unfolded_type(g, b0, b1, b2, b3) { }
-    template<typename B0, typename B1, typename B2, typename B3, typename B4>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) : unfolded_type(g, b0, b1, b2, b3, b4) { }
-    template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5) : unfolded_type(g, b0, b1, b2, b3, b4, b5) { }
-    template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) { }
-    template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) { }
-    template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7, typename B8>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7, B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) { }
-    template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7, typename B8, typename B9>
-    join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7, B8 b8, B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) { }
-    join_node(const join_node &other) : unfolded_type(other) {}
+    typedef typename unfolded_type::input_ports_type input_ports_type;
+
+    template<typename __TBB_B0, typename __TBB_B1>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1) : unfolded_type(g, b0, b1) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2) : unfolded_type(g, b0, b1, b2) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3) : unfolded_type(g, b0, b1, b2, b3) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4) :
+            unfolded_type(g, b0, b1, b2, b3, b4) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+#if __TBB_VARIADIC_MAX >= 6
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
+        typename __TBB_B5>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5) :
+            unfolded_type(g, b0, b1, b2, b3, b4, b5) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+#endif
+#if __TBB_VARIADIC_MAX >= 7
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
+        typename __TBB_B5, typename __TBB_B6>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6) :
+            unfolded_type(g, b0, b1, b2, b3, b4, b5, b6) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+#endif
+#if __TBB_VARIADIC_MAX >= 8
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
+        typename __TBB_B5, typename __TBB_B6, typename __TBB_B7>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
+            __TBB_B7 b7) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+#endif
+#if __TBB_VARIADIC_MAX >= 9
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
+        typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename __TBB_B8>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
+            __TBB_B7 b7, __TBB_B8 b8) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+#endif
+#if __TBB_VARIADIC_MAX >= 10
+    template<typename __TBB_B0, typename __TBB_B1, typename __TBB_B2, typename __TBB_B3, typename __TBB_B4,
+        typename __TBB_B5, typename __TBB_B6, typename __TBB_B7, typename __TBB_B8, typename __TBB_B9>
+    join_node(graph &g, __TBB_B0 b0, __TBB_B1 b1, __TBB_B2 b2, __TBB_B3 b3, __TBB_B4 b4, __TBB_B5 b5, __TBB_B6 b6,
+            __TBB_B7 b7, __TBB_B8 b8, __TBB_B9 b9) : unfolded_type(g, b0, b1, b2, b3, b4, b5, b6, b7, b8, b9) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+#endif
+    join_node(const join_node &other) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<OutputTuple,N>( tbb::internal::FLOW_JOIN_NODE_TAG_MATCHING, &this->my_graph,
+                                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+
 };
 
-#if TBB_PREVIEW_GRAPH_NODES
-// or node
-#include "internal/_flow_graph_or_impl.h"
+// indexer node
+#include "internal/_flow_graph_indexer_impl.h"
+
+struct indexer_null_type {};
 
-template<typename InputTuple>
-class or_node : public internal::unfolded_or_node<InputTuple> {
+template<typename T0, typename T1=indexer_null_type, typename T2=indexer_null_type, typename T3=indexer_null_type,
+                      typename T4=indexer_null_type, typename T5=indexer_null_type, typename T6=indexer_null_type,
+                      typename T7=indexer_null_type, typename T8=indexer_null_type, typename T9=indexer_null_type> class indexer_node;
+
+//indexer node specializations
+template<typename T0>
+class indexer_node<T0> : public internal::unfolded_indexer_node<tuple<T0> > {
 private:
-    static const int N = std::tuple_size<InputTuple>::value;
+    static const int N = 1;
 public:
-    typedef typename internal::or_output_type<InputTuple>::type output_type;
-    typedef typename internal::unfolded_or_node<InputTuple> unfolded_type;
-    or_node() : unfolded_type() { }
+    typedef tuple<T0> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
     // Copy constructor
-    or_node( const or_node& /*other*/ ) : unfolded_type() { }
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+     void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
 };
-#endif  // TBB_PREVIEW_GRAPH_NODES
+
+template<typename T0, typename T1>
+class indexer_node<T0, T1> : public internal::unfolded_indexer_node<tuple<T0, T1> > {
+private:
+    static const int N = 2;
+public:
+    typedef tuple<T0, T1> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+     void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+
+template<typename T0, typename T1, typename T2>
+class indexer_node<T0, T1, T2> : public internal::unfolded_indexer_node<tuple<T0, T1, T2> > {
+private:
+    static const int N = 3;
+public:
+    typedef tuple<T0, T1, T2> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+        void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+
+template<typename T0, typename T1, typename T2, typename T3>
+class indexer_node<T0, T1, T2, T3> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3> > {
+private:
+    static const int N = 4;
+public:
+    typedef tuple<T0, T1, T2, T3> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+
+template<typename T0, typename T1, typename T2, typename T3, typename T4>
+class indexer_node<T0, T1, T2, T3, T4> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4> > {
+private:
+    static const int N = 5;
+public:
+    typedef tuple<T0, T1, T2, T3, T4> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+
+#if __TBB_VARIADIC_MAX >= 6
+template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5>
+class indexer_node<T0, T1, T2, T3, T4, T5> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5> > {
+private:
+    static const int N = 6;
+public:
+    typedef tuple<T0, T1, T2, T3, T4, T5> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+#endif //variadic max 6
+
+#if __TBB_VARIADIC_MAX >= 7
+template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
+         typename T6>
+class indexer_node<T0, T1, T2, T3, T4, T5, T6> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6> > {
+private:
+    static const int N = 7;
+public:
+    typedef tuple<T0, T1, T2, T3, T4, T5, T6> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+#endif //variadic max 7
+
+#if __TBB_VARIADIC_MAX >= 8
+template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
+         typename T6, typename T7>
+class indexer_node<T0, T1, T2, T3, T4, T5, T6, T7> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6, T7> > {
+private:
+    static const int N = 8;
+public:
+    typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+#endif //variadic max 8
+
+#if __TBB_VARIADIC_MAX >= 9
+template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
+         typename T6, typename T7, typename T8>
+class indexer_node<T0, T1, T2, T3, T4, T5, T6, T7, T8> : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> > {
+private:
+    static const int N = 9;
+public:
+    typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+#endif //variadic max 9
+
+#if __TBB_VARIADIC_MAX >= 10
+template<typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
+         typename T6, typename T7, typename T8, typename T9>
+class indexer_node/*default*/ : public internal::unfolded_indexer_node<tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> > {
+private:
+    static const int N = 10;
+public:
+    typedef tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> InputTuple;
+    typedef typename internal::tagged_msg<size_t, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> output_type;
+    typedef typename internal::unfolded_indexer_node<InputTuple> unfolded_type;
+    indexer_node(graph& g) : unfolded_type(g) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+    // Copy constructor
+    indexer_node( const indexer_node& other ) : unfolded_type(other) {
+        tbb::internal::fgt_multiinput_node<InputTuple,N>( tbb::internal::FLOW_INDEXER_NODE, &this->my_graph,
+                                           this->input_ports(), static_cast< sender< output_type > *>(this) );
+    }
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+    /* override */ void set_name( const char *name ) {
+        tbb::internal::fgt_node_desc( this, name );
+    }
+#endif
+};
+#endif //variadic max 10
 
 //! Makes an edge between a single predecessor and a single successor
 template< typename T >
 inline void make_edge( sender<T> &p, receiver<T> &s ) {
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    s.internal_add_built_predecessor(p);
+    p.internal_add_built_successor(s);
+#endif
     p.register_successor( s );
+    tbb::internal::fgt_make_edge( &p, &s );
 }
-        
+
 //! Makes an edge between a single predecessor and a single successor
 template< typename T >
 inline void remove_edge( sender<T> &p, receiver<T> &s ) {
     p.remove_successor( s );
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    // TODO: should we try to remove p from the predecessor list of s, in case the edge is reversed?
+    p.internal_delete_built_successor(s);
+    s.internal_delete_built_predecessor(p);
+#endif
+    tbb::internal::fgt_remove_edge( &p, &s );
 }
 
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+template<typename C >
+template< typename S >
+void edge_container<C>::sender_extract( S &s ) {
+    edge_vector e = built_edges;
+    for ( typename edge_vector::iterator i = e.begin(); i != e.end(); ++i ) {
+        remove_edge(s, **i);
+    }
+}
+
+template<typename C >
+template< typename R >
+void edge_container<C>::receiver_extract( R &r ) {
+    edge_vector e = built_edges;
+    for ( typename edge_vector::iterator i = e.begin(); i != e.end(); ++i ) {
+        remove_edge(**i, r);
+    }
+}
+#endif
+
 //! Returns a copy of the body from a function or continue node
 template< typename Body, typename Node >
 Body copy_body( Node &n ) {
     return n.template copy_function_object<Body>();
 }
-        
-        
-} // interface6
-
-    using interface6::graph;
-    using interface6::graph_node;
-    using interface6::continue_msg;
-    using interface6::sender;
-    using interface6::receiver;
-    using interface6::continue_receiver;
-
-    using interface6::source_node;
-    using interface6::function_node;
-#if TBB_PREVIEW_GRAPH_NODES
-    using interface6::multioutput_function_node;
-    using interface6::split_node;
-    using interface6::internal::output_port;
-    using interface6::or_node;
-#endif
-    using interface6::continue_node;
-    using interface6::overwrite_node;
-    using interface6::write_once_node;
-    using interface6::broadcast_node;
-    using interface6::buffer_node;
-    using interface6::queue_node;
-    using interface6::sequencer_node;
-    using interface6::priority_queue_node;
-    using interface6::limiter_node;
-    using namespace interface6::internal::graph_policy_namespace;
-    using interface6::join_node;
-    using interface6::input_port;
-    using interface6::copy_body; 
-    using interface6::make_edge; 
-    using interface6::remove_edge; 
-    using interface6::internal::NO_TAG;
-    using interface6::internal::tag_value;
+
+} // interface7
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    using interface7::reset_flags;
+    using interface7::rf_reset_protocol;
+    using interface7::rf_reset_bodies;
+    using interface7::rf_extract;
+#endif
+
+    using interface7::graph;
+    using interface7::graph_node;
+    using interface7::continue_msg;
+    using interface7::sender;
+    using interface7::receiver;
+    using interface7::continue_receiver;
+
+    using interface7::source_node;
+    using interface7::function_node;
+    using interface7::multifunction_node;
+    using interface7::split_node;
+    using interface7::internal::output_port;
+    using interface7::indexer_node;
+    using interface7::internal::tagged_msg;
+    using interface7::internal::cast_to;
+    using interface7::internal::is_a;
+    using interface7::continue_node;
+    using interface7::overwrite_node;
+    using interface7::write_once_node;
+    using interface7::broadcast_node;
+    using interface7::buffer_node;
+    using interface7::queue_node;
+    using interface7::sequencer_node;
+    using interface7::priority_queue_node;
+    using interface7::limiter_node;
+    using namespace interface7::internal::graph_policy_namespace;
+    using interface7::join_node;
+    using interface7::input_port;
+    using interface7::copy_body;
+    using interface7::make_edge;
+    using interface7::remove_edge;
+    using interface7::internal::NO_TAG;
+    using interface7::internal::tag_value;
 
 } // flow
 } // tbb
 
+#undef __TBB_PFG_RESET_ARG
+#undef __TBB_COMMA
+
 #endif // __TBB_flow_graph_H
index 5eaf53e36986cf4682125a3e1c5663975506f896..6ceb5da619d462179bb169fc20d1174606ae6c24 100644 (file)
@@ -2,22 +2,24 @@
 <BODY>
 
 <H2>Overview</H2>
-Include files for Threading Building Blocks classes and functions.
+Include files for Intel&reg; Threading Building Blocks classes and functions.
 
 <BR><A HREF=".">Click here</A> to see all files in the directory.
 
 <H2>Directories</H2>
 <DL>
-<DT><A HREF="machine">machine</A>
-<DD>Include files for low-level architecture specific functionality.
 <DT><A HREF="compat">compat</A>
 <DD>Include files for source level compatibility with other frameworks.
+<DT><A HREF="internal">internal</A>
+<DD>Include files with implementation details; not for direct use.
+<DT><A HREF="machine">machine</A>
+<DD>Include files for low-level architecture specific functionality; not for direct use.
 </DL>
 
 <HR>
 <A HREF="../index.html">Up to parent directory</A>
 <p></p>
-Copyright &copy; 2005-2011 Intel Corporation.  All Rights Reserved.
+Copyright &copy; 2005-2014 Intel Corporation.  All Rights Reserved.
 <P></P>
 Intel is a registered trademark or trademark of Intel Corporation
 or its subsidiaries in the United States and other countries.
index 33384c145b17f4e835f606819361b440cfff889d..854cb4eef1f0e699974562f5c5c1f463c0a35ad6 100644 (file)
@@ -1,36 +1,30 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__aggregator_impl_H
 #define __TBB__aggregator_impl_H
 
 #include "../atomic.h"
+#if !__TBBMALLOC_BUILD
 #include "../tbb_profiling.h"
+#endif
 
 namespace tbb {
 namespace interface6 {
@@ -53,21 +47,26 @@ class aggregated_operation {
     aggregated_operation. The parameter handler_type is a functor that will be passed the
     list of operations and is expected to handle each operation appropriately, setting the
     status of each operation to non-zero.*/
- template < typename handler_type, typename operation_type >
-class aggregator {
- public:
-    aggregator() : handler_busy(false) { pending_operations = NULL; }
-    explicit aggregator(handler_type h) : handler_busy(false), handle_operations(h) {
-        pending_operations = NULL; 
-    }
-
-    void initialize_handler(handler_type h) { handle_operations = h; }
+template < typename operation_type >
+class aggregator_generic {
+public:
+    aggregator_generic() : handler_busy(false) { pending_operations = NULL; }
 
     //! Place operation in list
     /** Place operation in list and either handle list or wait for operation to
-        complete.  */
-    void execute(operation_type *op) {
+        complete.
+        long_life_time specifies life time of an operation inserting in an aggregator.
+        "Long" (long_life_time == true) life time operation can be accessed
+        even after executing it.
+        "Short" (long_life_time == false) life time operations can be destroyed
+        during executing so any access to it after executing is invalid.*/
+    template < typename handler_type >
+    void execute(operation_type *op, handler_type &handle_operations, bool long_life_time = true) {
         operation_type *res;
+        // op->status should be read before inserting the operation in the
+        // aggregator queue since it can become invalid after executing a
+        // handler (if the operation has 'short' life time.)
+        const uintptr_t status = op->status;
 
         // ITT note: &(op->status) tag is used to cover accesses to this op node. This
         // thread has created the operation, and now releases it so that the handler
@@ -75,21 +74,25 @@ class aggregator {
         // thus this tag will be acquired just before the operation is handled in the
         // handle_operations functor.
         call_itt_notify(releasing, &(op->status));
-        // insert the operation in the queue
+        // insert the operation in the queue.
         do {
             // ITT may flag the following line as a race; it is a false positive:
             // This is an atomic read; we don't provide itt_hide_load_word for atomics
-            op->next = res = pending_operations; // NOT A RACE 
+            op->next = res = pending_operations; // NOT A RACE
         } while (pending_operations.compare_and_swap(op, res) != res);
-        if (!res) { // first in the list; handle the operations
+        if (!res) { // first in the list; handle the operations.
             // ITT note: &pending_operations tag covers access to the handler_busy flag,
             // which this waiting handler thread will try to set before entering
             // handle_operations.
             call_itt_notify(acquired, &pending_operations);
-            start_handle_operations();
-            __TBB_ASSERT(op->status, NULL);
+            start_handle_operations(handle_operations);
+            // The operation with 'short' life time can already be destroyed.
+            if (long_life_time)
+                __TBB_ASSERT(op->status, NULL);
         }
-        else { // not first; wait for op to be ready
+        // not first; wait for op to be ready.
+        else if (!status) { // operation is blocking here.
+            __TBB_ASSERT(long_life_time, "The blocking operation cannot have 'short' life time. Since it can already be destroyed.");
             call_itt_notify(prepare, &(op->status));
             spin_wait_while_eq(op->status, uintptr_t(0));
             itt_load_word_with_acquire(op->status);
@@ -101,10 +104,10 @@ class aggregator {
     atomic<operation_type *> pending_operations;
     //! Controls thread access to handle_operations
     uintptr_t handler_busy;
-    handler_type handle_operations;
 
     //! Trigger the handling of operations when the handler is free
-    void start_handle_operations() {
+    template < typename handler_type >
+    void start_handle_operations( handler_type &handle_operations ) {
         operation_type *op_list;
 
         // ITT note: &handler_busy tag covers access to pending_operations as it is passed
@@ -137,6 +140,20 @@ class aggregator {
     }
 };
 
+template < typename handler_type, typename operation_type >
+class aggregator : public aggregator_generic<operation_type> {
+    handler_type handle_operations;
+public:
+    aggregator() {}
+    explicit aggregator(handler_type h) : handle_operations(h) {}
+
+    void initialize_handler(handler_type h) { handle_operations = h; }
+
+    void execute(operation_type *op) {
+        aggregator_generic<operation_type>::execute(op, handle_operations);
+    }
+};
+
 // the most-compatible friend declaration (vs, gcc, icc) is
 //    template<class U, class V> friend class aggregating_functor;
 template<typename aggregating_class, typename operation_list>
@@ -153,6 +170,7 @@ public:
 
 namespace internal {
     using interface6::internal::aggregated_operation;
+    using interface6::internal::aggregator_generic;
     using interface6::internal::aggregator;
     using interface6::internal::aggregating_functor;
 } // namespace internal
index 4d6adbbd2945ca9a2a744d0310b74c3daf7913e1..8d95cc69ee784d083acaac869d534673679d785a 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__concurrent_queue_impl_H
@@ -41,6 +33,7 @@
 #include "../tbb_exception.h"
 #include "../tbb_profiling.h"
 #include <new>
+#include <utility>
 
 #if !TBB_USE_EXCEPTIONS && _MSC_VER
     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
@@ -65,9 +58,6 @@ template<typename T, typename A> class concurrent_queue;
 
 template<typename T, typename A> class concurrent_bounded_queue;
 
-namespace deprecated {
-template<typename T, typename A> class concurrent_queue;
-}
 #endif
 
 //! For internal use only.
@@ -83,6 +73,7 @@ typedef size_t ticket;
 template<typename T> class micro_queue ;
 template<typename T> class micro_queue_pop_finalizer ;
 template<typename T> class concurrent_queue_base_v3;
+template<typename T> struct concurrent_queue_rep;
 
 //! parts of concurrent_queue_rep that do not have references to micro_queue
 /**
@@ -103,7 +94,7 @@ public:
     //! Prefix on a page
     struct page {
         page* next;
-        uintptr_t mask; 
+        uintptr_t mask;
     };
 
     atomic<ticket> head_counter;
@@ -153,28 +144,34 @@ private:
     The caller is expected to zero-initialize it. */
 template<typename T>
 class micro_queue : no_copy {
+public:
+    typedef void (*item_constructor_t)(T* location, const void* src);
+private:
     typedef concurrent_queue_rep_base::page page;
 
-    //! Class used to ensure exception-safety of method "pop" 
+    //! Class used to ensure exception-safety of method "pop"
     class destroyer: no_copy {
         T& my_value;
     public:
         destroyer( T& value ) : my_value(value) {}
-        ~destroyer() {my_value.~T();}          
+        ~destroyer() {my_value.~T();}
     };
 
-    void copy_item( page& dst, size_t index, const void* src ) {
-        new( &get_ref(dst,index) ) T(*static_cast<const T*>(src)); 
+    void copy_item( page& dst, size_t dindex, const void* src, item_constructor_t construct_item ) {
+        construct_item( &get_ref(dst, dindex), src );
     }
 
-    void copy_item( page& dst, size_t dindex, const page& src, size_t sindex ) {
-        new( &get_ref(dst,dindex) ) T( get_ref(const_cast<page&>(src),sindex) );
+    void copy_item( page& dst, size_t dindex, const page& src, size_t sindex,
+        item_constructor_t construct_item )
+    {
+        T& src_item = get_ref( const_cast<page&>(src), sindex );
+        construct_item( &get_ref(dst, dindex), static_cast<const void*>(&src_item) );
     }
 
     void assign_and_destroy_item( void* dst, page& src, size_t index ) {
         T& from = get_ref(src,index);
         destroyer d(from);
-        *static_cast<T*>(dst) = from;
+        *static_cast<T*>(dst) = tbb::internal::move( from );
     }
 
     void spin_wait_until_my_turn( atomic<ticket>& counter, ticket k, concurrent_queue_rep_base& rb ) const ;
@@ -184,7 +181,7 @@ public:
 
     struct padded_page: page {
         //! Not defined anywhere - exists to quiet warnings.
-        padded_page(); 
+        padded_page();
         //! Not defined anywhere - exists to quiet warnings.
         void operator=( const padded_page& );
         //! Must be last field.
@@ -202,35 +199,40 @@ public:
     atomic<ticket> tail_counter;
 
     spin_mutex page_mutex;
-    
-    void push( const void* item, ticket k, concurrent_queue_base_v3<T>& base ) ;
+
+    void push( const void* item, ticket k, concurrent_queue_base_v3<T>& base,
+        item_constructor_t construct_item ) ;
 
     bool pop( void* dst, ticket k, concurrent_queue_base_v3<T>& base ) ;
 
-    micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3<T>& base ) ;
+    micro_queue& assign( const micro_queue& src, concurrent_queue_base_v3<T>& base,
+        item_constructor_t construct_item ) ;
 
-    page* make_copy( concurrent_queue_base_v3<T>& base, const page* src_page, size_t begin_in_page, size_t end_in_page, ticket& g_index ) ;
+    page* make_copy( concurrent_queue_base_v3<T>& base, const page* src_page, size_t begin_in_page,
+        size_t end_in_page, ticket& g_index, item_constructor_t construct_item ) ;
 
     void invalidate_page_and_rethrow( ticket k ) ;
 };
 
 template<typename T>
 void micro_queue<T>::spin_wait_until_my_turn( atomic<ticket>& counter, ticket k, concurrent_queue_rep_base& rb ) const {
-    atomic_backoff backoff;
-    do {
-        backoff.pause();
-        if( counter&1 ) {
+    for( atomic_backoff b(true);;b.pause() ) {
+        ticket c = counter;
+        if( c==k ) return;
+        else if( c&1 ) {
             ++rb.n_invalid_entries;
             throw_exception( eid_bad_last_alloc );
         }
-    } while( counter!=k ) ;
+    }
 }
 
 template<typename T>
-void micro_queue<T>::push( const void* item, ticket k, concurrent_queue_base_v3<T>& base ) {
+void micro_queue<T>::push( const void* item, ticket k, concurrent_queue_base_v3<T>& base,
+    item_constructor_t construct_item )
+{
     k &= -concurrent_queue_rep_base::n_queue;
     page* p = NULL;
-    size_t index = k/concurrent_queue_rep_base::n_queue & (base.my_rep->items_per_page-1);
+    size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page);
     if( !index ) {
         __TBB_TRY {
             concurrent_queue_page_allocator& pa = base;
@@ -243,30 +245,31 @@ void micro_queue<T>::push( const void* item, ticket k, concurrent_queue_base_v3<
         p->next = NULL;
     }
 
-    if( tail_counter!=k ) spin_wait_until_my_turn( tail_counter, k, *base.my_rep );
+    if( tail_counter != k ) spin_wait_until_my_turn( tail_counter, k, *base.my_rep );
     call_itt_notify(acquired, &tail_counter);
-        
+
     if( p ) {
         spin_mutex::scoped_lock lock( page_mutex );
         page* q = tail_page;
         if( is_valid_page(q) )
             q->next = p;
         else
-            head_page = p; 
+            head_page = p;
         tail_page = p;
     } else {
         p = tail_page;
     }
+
     __TBB_TRY {
-        copy_item( *p, index, item );
+        copy_item( *p, index, item, construct_item );
         // If no exception was thrown, mark item as present.
         itt_hide_store_word(p->mask,  p->mask | uintptr_t(1)<<index);
         call_itt_notify(releasing, &tail_counter);
-        tail_counter += concurrent_queue_rep_base::n_queue; 
+        tail_counter += concurrent_queue_rep_base::n_queue;
     } __TBB_CATCH (...) {
         ++base.my_rep->n_invalid_entries;
         call_itt_notify(releasing, &tail_counter);
-        tail_counter += concurrent_queue_rep_base::n_queue; 
+        tail_counter += concurrent_queue_rep_base::n_queue;
         __TBB_RETHROW();
     }
 }
@@ -280,10 +283,10 @@ bool micro_queue<T>::pop( void* dst, ticket k, concurrent_queue_base_v3<T>& base
     call_itt_notify(acquired, &tail_counter);
     page& p = *head_page;
     __TBB_ASSERT( &p, NULL );
-    size_t index = k/concurrent_queue_rep_base::n_queue & (base.my_rep->items_per_page-1);
-    bool success = false; 
+    size_t index = modulo_power_of_two( k/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page );
+    bool success = false;
     {
-        micro_queue_pop_finalizer<T> finalizer( *this, base, k+concurrent_queue_rep_base::n_queue, index==base.my_rep->items_per_page-1 ? &p : NULL ); 
+        micro_queue_pop_finalizer<T> finalizer( *this, base, k+concurrent_queue_rep_base::n_queue, index==base.my_rep->items_per_page-1 ? &p : NULL );
         if( p.mask & uintptr_t(1)<<index ) {
             success = true;
             assign_and_destroy_item( dst, p, index );
@@ -295,33 +298,34 @@ bool micro_queue<T>::pop( void* dst, ticket k, concurrent_queue_base_v3<T>& base
 }
 
 template<typename T>
-micro_queue<T>& micro_queue<T>::assign( const micro_queue<T>& src, concurrent_queue_base_v3<T>& base ) {
+micro_queue<T>& micro_queue<T>::assign( const micro_queue<T>& src, concurrent_queue_base_v3<T>& base,
+    item_constructor_t construct_item )
+{
     head_counter = src.head_counter;
     tail_counter = src.tail_counter;
-    page_mutex   = src.page_mutex;
 
     const page* srcp = src.head_page;
     if( is_valid_page(srcp) ) {
         ticket g_index = head_counter;
         __TBB_TRY {
             size_t n_items  = (tail_counter-head_counter)/concurrent_queue_rep_base::n_queue;
-            size_t index = head_counter/concurrent_queue_rep_base::n_queue & (base.my_rep->items_per_page-1);
+            size_t index = modulo_power_of_two( head_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page );
             size_t end_in_first_page = (index+n_items<base.my_rep->items_per_page)?(index+n_items):base.my_rep->items_per_page;
 
-            head_page = make_copy( base, srcp, index, end_in_first_page, g_index );
+            head_page = make_copy( base, srcp, index, end_in_first_page, g_index, construct_item );
             page* cur_page = head_page;
 
             if( srcp != src.tail_page ) {
                 for( srcp = srcp->next; srcp!=src.tail_page; srcp=srcp->next ) {
-                    cur_page->next = make_copy( base, srcp, 0, base.my_rep->items_per_page, g_index );
+                    cur_page->next = make_copy( base, srcp, 0, base.my_rep->items_per_page, g_index, construct_item );
                     cur_page = cur_page->next;
                 }
 
                 __TBB_ASSERT( srcp==src.tail_page, NULL );
-                size_t last_index = tail_counter/concurrent_queue_rep_base::n_queue & (base.my_rep->items_per_page-1);
+                size_t last_index = modulo_power_of_two( tail_counter/concurrent_queue_rep_base::n_queue, base.my_rep->items_per_page );
                 if( last_index==0 ) last_index = base.my_rep->items_per_page;
 
-                cur_page->next = make_copy( base, srcp, 0, last_index, g_index );
+                cur_page->next = make_copy( base, srcp, 0, last_index, g_index, construct_item );
                 cur_page = cur_page->next;
             }
             tail_page = cur_page;
@@ -352,14 +356,17 @@ void micro_queue<T>::invalidate_page_and_rethrow( ticket k ) {
 }
 
 template<typename T>
-concurrent_queue_rep_base::page* micro_queue<T>::make_copy( concurrent_queue_base_v3<T>& base, const concurrent_queue_rep_base::page* src_page, size_t begin_in_page, size_t end_in_page, ticket& g_index ) {
+concurrent_queue_rep_base::page* micro_queue<T>::make_copy( concurrent_queue_base_v3<T>& base,
+    const concurrent_queue_rep_base::page* src_page, size_t begin_in_page, size_t end_in_page,
+    ticket& g_index, item_constructor_t construct_item )
+{
     concurrent_queue_page_allocator& pa = base;
     page* new_page = pa.allocate_page();
     new_page->next = NULL;
     new_page->mask = src_page->mask;
     for( ; begin_in_page!=end_in_page; ++begin_in_page, ++g_index )
         if( new_page->mask & uintptr_t(1)<<begin_in_page )
-            copy_item( *new_page, begin_in_page, *src_page, begin_in_page );
+            copy_item( *new_page, begin_in_page, *src_page, begin_in_page, construct_item );
     return new_page;
 }
 
@@ -368,7 +375,7 @@ class micro_queue_pop_finalizer: no_copy {
     typedef concurrent_queue_rep_base::page page;
     ticket my_ticket;
     micro_queue<T>& my_queue;
-    page* my_page; 
+    page* my_page;
     concurrent_queue_page_allocator& allocator;
 public:
     micro_queue_pop_finalizer( micro_queue<T>& queue, concurrent_queue_base_v3<T>& b, ticket k, page* p ) :
@@ -427,6 +434,7 @@ struct concurrent_queue_rep : public concurrent_queue_rep_base {
  */
 template<typename T>
 class concurrent_queue_base_v3: public concurrent_queue_page_allocator {
+private:
     //! Internal representation
     concurrent_queue_rep<T>* my_rep;
 
@@ -440,6 +448,7 @@ protected:
 
 private:
     typedef typename micro_queue<T>::padded_page padded_page;
+    typedef typename micro_queue<T>::item_constructor_t item_constructor_t;
 
     /* override */ virtual page *allocate_page() {
         concurrent_queue_rep<T>& r = *my_rep;
@@ -472,10 +481,10 @@ protected:
     }
 
     //! Enqueue item at tail of queue
-    void internal_push( const void* src ) {
-        concurrent_queue_rep<T>& r = *my_rep;
-        ticket k = r.tail_counter++;
-        r.choose(k).push( src, k, *this );
+    void internal_push( const void* src, item_constructor_t construct_item ) {
+         concurrent_queue_rep<T>& r = *my_rep;
+         ticket k = r.tail_counter++;
+         r.choose(k).push( src, k, *this, construct_item );
     }
 
     //! Attempt to dequeue item from queue.
@@ -497,8 +506,15 @@ protected:
         throw_exception( eid_bad_alloc );
     }
 
-    //! copy internal representation
-    void assign( const concurrent_queue_base_v3& src ) ;
+    //! copy or move internal representation
+    void assign( const concurrent_queue_base_v3& src, item_constructor_t construct_item ) ;
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! swap internal representation
+    void internal_swap( concurrent_queue_base_v3& src ) {
+        std::swap( my_rep, src.my_rep );
+    }
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
 };
 
 template<typename T>
@@ -511,11 +527,11 @@ concurrent_queue_base_v3<T>::concurrent_queue_base_v3() {
     __TBB_ASSERT( (size_t)&my_rep->array % NFS_GetLineSize()==0, "alignment error" );
     memset(my_rep,0,sizeof(concurrent_queue_rep<T>));
     my_rep->item_size = item_size;
-    my_rep->items_per_page = item_size<=8 ? 32 :
-                             item_size<=16 ? 16 : 
-                             item_size<=32 ? 8 :
-                             item_size<=64 ? 4 :
-                             item_size<=128 ? 2 :
+    my_rep->items_per_page = item_size<=  8 ? 32 :
+                             item_size<= 16 ? 16 :
+                             item_size<= 32 ?  8 :
+                             item_size<= 64 ?  4 :
+                             item_size<=128 ?  2 :
                              1;
 }
 
@@ -526,8 +542,8 @@ bool concurrent_queue_base_v3<T>::internal_try_pop( void* dst ) {
     do {
         k = r.head_counter;
         for(;;) {
-            if( r.tail_counter<=k ) {
-                // Queue is empty 
+            if( (ptrdiff_t)(r.tail_counter-k)<=0 ) {
+                // Queue is empty
                 return false;
             }
             // Queue had item with ticket k when we looked.  Attempt to get that item.
@@ -579,26 +595,28 @@ void concurrent_queue_base_v3<T>::internal_finish_clear() {
             __TBB_ASSERT( r.array[i].head_page==tp, "at most one page should remain" );
             deallocate_page( tp );
             r.array[i].tail_page = NULL;
-        } else 
+        } else
             __TBB_ASSERT( !is_valid_page(r.array[i].head_page), "head page pointer corrupt?" );
     }
 }
 
 template<typename T>
-void concurrent_queue_base_v3<T>::assign( const concurrent_queue_base_v3& src ) {
+void concurrent_queue_base_v3<T>::assign( const concurrent_queue_base_v3& src,
+    item_constructor_t construct_item )
+{
     concurrent_queue_rep<T>& r = *my_rep;
     r.items_per_page = src.my_rep->items_per_page;
 
-    // copy concurrent_queue_rep.
+    // copy concurrent_queue_rep data
     r.head_counter = src.my_rep->head_counter;
     r.tail_counter = src.my_rep->tail_counter;
     r.n_invalid_entries = src.my_rep->n_invalid_entries;
 
-    // copy micro_queues
-    for( size_t i = 0; i<r.n_queue; ++i )
-        r.array[i].assign( src.my_rep->array[i], *this);
+    // copy or move micro_queues
+    for( size_t i = 0; i < r.n_queue; ++i )
+        r.array[i].assign( src.my_rep->array[i], *this, construct_item);
 
-    __TBB_ASSERT( r.head_counter==src.my_rep->head_counter && r.tail_counter==src.my_rep->tail_counter, 
+    __TBB_ASSERT( r.head_counter==src.my_rep->head_counter && r.tail_counter==src.my_rep->tail_counter,
             "the source concurrent queue should not be concurrently modified." );
 }
 
@@ -631,7 +649,7 @@ bool concurrent_queue_iterator_rep<T>::get_item( T*& item, size_t k ) {
     } else {
         typename concurrent_queue_base_v3<T>::page* p = array[concurrent_queue_rep<T>::index(k)];
         __TBB_ASSERT(p,NULL);
-        size_t i = k/concurrent_queue_rep<T>::n_queue & (my_queue.my_rep->items_per_page-1);
+        size_t i = modulo_power_of_two( k/concurrent_queue_rep<T>::n_queue, my_queue.my_rep->items_per_page );
         item = &micro_queue<T>::get_ref(*p,i);
         return (p->mask & uintptr_t(1)<<i)!=0;
     }
@@ -708,7 +726,7 @@ void concurrent_queue_iterator_base_v3<Value>::assign( const concurrent_queue_it
 
 template<typename Value>
 void concurrent_queue_iterator_base_v3<Value>::advance() {
-    __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" );  
+    __TBB_ASSERT( my_item, "attempt to increment iterator past end of queue" );
     size_t k = my_rep->head_counter;
     const concurrent_queue_base_v3<Value>& queue = my_rep->my_queue;
 #if TBB_USE_ASSERT
@@ -716,7 +734,7 @@ void concurrent_queue_iterator_base_v3<Value>::advance() {
     my_rep->get_item(tmp,k);
     __TBB_ASSERT( my_item==tmp, NULL );
 #endif /* TBB_USE_ASSERT */
-    size_t i = k/concurrent_queue_rep<Value>::n_queue & (queue.my_rep->items_per_page-1);
+    size_t i = modulo_power_of_two( k/concurrent_queue_rep<Value>::n_queue, queue.my_rep->items_per_page );
     if( i==queue.my_rep->items_per_page-1 ) {
         typename concurrent_queue_base_v3<Value>::page*& root = my_rep->array[concurrent_queue_rep<Value>::index(k)];
         root = root->next;
@@ -743,8 +761,8 @@ class concurrent_queue_iterator: public concurrent_queue_iterator_base_v3<typena
     template<typename T, class A>
     friend class ::tbb::strict_ppl::concurrent_queue;
 #else
-public: // workaround for MSVC
-#endif 
+public:
+#endif
     //! Construct iterator pointing to head of queue.
     concurrent_queue_iterator( const concurrent_queue_base_v3<Value>& queue ) :
         concurrent_queue_iterator_base_v3<typename tbb_remove_cv<Value>::type>(queue)
@@ -764,7 +782,7 @@ public:
         return *this;
     }
 
-    //! Reference to current item 
+    //! Reference to current item
     Value& operator*() const {
         return *static_cast<Value*>(this->my_item);
     }
@@ -814,6 +832,7 @@ template<typename Container, typename Value> class concurrent_queue_iterator;
 /** Type-independent portion of concurrent_queue.
     @ingroup containers */
 class concurrent_queue_base_v3: no_copy {
+private:
     //! Internal representation
     concurrent_queue_rep* my_rep;
 
@@ -826,25 +845,27 @@ protected:
     //! Prefix on a page
     struct page {
         page* next;
-        uintptr_t mask; 
+        uintptr_t mask;
     };
 
     //! Capacity of the queue
     ptrdiff_t my_capacity;
-   
+
     //! Always a power of 2
     size_t items_per_page;
 
     //! Size of an item
     size_t item_size;
 
-#if __TBB_GCC_3_3_PROTECTED_BROKEN
+    enum copy_specifics { copy, move };
+
+#if __TBB_PROTECTED_NESTED_CLASS_BROKEN
 public:
 #endif
     template<typename T>
     struct padded_page: page {
         //! Not defined anywhere - exists to quiet warnings.
-        padded_page(); 
+        padded_page();
         //! Not defined anywhere - exists to quiet warnings.
         void operator=( const padded_page& );
         //! Must be last field.
@@ -858,13 +879,16 @@ protected:
     __TBB_EXPORTED_METHOD concurrent_queue_base_v3( size_t item_size );
     virtual __TBB_EXPORTED_METHOD ~concurrent_queue_base_v3();
 
-    //! Enqueue item at tail of queue
+    //! Enqueue item at tail of queue using copy operation
     void __TBB_EXPORTED_METHOD internal_push( const void* src );
 
     //! Dequeue item from head of queue
     void __TBB_EXPORTED_METHOD internal_pop( void* dst );
 
-    //! Attempt to enqueue item onto queue.
+    //! Abort all pending queue operations
+    void __TBB_EXPORTED_METHOD internal_abort();
+
+    //! Attempt to enqueue item onto queue using copy operation
     bool __TBB_EXPORTED_METHOD internal_push_if_not_full( const void* src );
 
     //! Attempt to dequeue item from queue.
@@ -896,10 +920,49 @@ protected:
     //! copy internal representation
     void __TBB_EXPORTED_METHOD assign( const concurrent_queue_base_v3& src ) ;
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //! swap queues
+    void internal_swap( concurrent_queue_base_v3& src ) {
+        std::swap( my_capacity, src.my_capacity );
+        std::swap( items_per_page, src.items_per_page );
+        std::swap( item_size, src.item_size );
+        std::swap( my_rep, src.my_rep );
+    }
+#endif /* __TBB_CPP11_RVALUE_REF_PRESENT */
+
+    //! Enqueues item at tail of queue using specified operation (copy or move)
+    void internal_insert_item( const void* src, copy_specifics op_type );
+
+    //! Attempts to enqueue at tail of queue using specified operation (copy or move)
+    bool internal_insert_if_not_full( const void* src, copy_specifics op_type );
+
+    //! Assigns one queue to another using specified operation (copy or move)
+    void internal_assign( const concurrent_queue_base_v3& src, copy_specifics op_type );
 private:
     virtual void copy_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0;
 };
 
+//! For internal use only.
+/** Backward compatible modification of concurrent_queue_base_v3
+    @ingroup containers */
+class concurrent_queue_base_v8: public concurrent_queue_base_v3 {
+protected:
+    concurrent_queue_base_v8( size_t item_sz ) : concurrent_queue_base_v3( item_sz ) {}
+
+    //! move items
+    void __TBB_EXPORTED_METHOD move_content( concurrent_queue_base_v8& src ) ;
+
+    //! Attempt to enqueue item onto queue using move operation
+    bool __TBB_EXPORTED_METHOD internal_push_move_if_not_full( const void* src );
+
+    //! Enqueue item at tail of queue using move operation
+    void __TBB_EXPORTED_METHOD internal_push_move( const void* src );
+private:
+    friend struct micro_queue;
+    virtual void move_page_item( page& dst, size_t dindex, const page& src, size_t sindex ) = 0;
+    virtual void move_item( page& dst, size_t index, const void* src ) = 0;
+};
+
 //! Type-independent portion of concurrent_queue_iterator.
 /** @ingroup containers */
 class concurrent_queue_iterator_base_v3 {
@@ -955,12 +1018,10 @@ class concurrent_queue_iterator: public concurrent_queue_iterator_base,
 #if !defined(_MSC_VER) || defined(__INTEL_COMPILER)
     template<typename T, class A>
     friend class ::tbb::concurrent_bounded_queue;
-
-    template<typename T, class A>
-    friend class ::tbb::deprecated::concurrent_queue;
 #else
 public: // workaround for MSVC
-#endif 
+#endif
+
     //! Construct iterator pointing to head of queue.
     concurrent_queue_iterator( const concurrent_queue_base_v3& queue ) :
         concurrent_queue_iterator_base_v3(queue,__TBB_offsetof(concurrent_queue_base_v3::padded_page<Value>,last))
@@ -970,7 +1031,7 @@ public: // workaround for MSVC
 public:
     concurrent_queue_iterator() {}
 
-    /** If Value==Container::value_type, then this routine is the copy constructor. 
+    /** If Value==Container::value_type, then this routine is the copy constructor.
         If Value==const Container::value_type, then this routine is a conversion constructor. */
     concurrent_queue_iterator( const concurrent_queue_iterator<Container,typename Container::value_type>& other ) :
         concurrent_queue_iterator_base_v3(other)
@@ -982,7 +1043,7 @@ public:
         return *this;
     }
 
-    //! Reference to current item 
+    //! Reference to current item
     Value& operator*() const {
         return *static_cast<Value*>(my_item);
     }
index 94227287ccc1e704077a8e825033d51b8ddf8aed..103654276ff780084d9db86292747a2f418697b7 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 /* Container implementations in this header are based on PPL implementations 
 
 #include <iterator>
 #include <utility>      // Need std::pair
-#include <functional>
+#include <functional>   // Need std::equal_to (in ../concurrent_unordered_*.h)
 #include <string>       // For tbb_hasher
 #include <cstring>      // Need std::memset
+#include <algorithm>    // Need std::swap
 
 #if !TBB_USE_EXCEPTIONS && _MSC_VER
     #pragma warning (pop)
 #include "../tbb_exception.h"
 #include "../tbb_allocator.h"
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    #include <initializer_list>
+#endif
+
 namespace tbb {
 namespace interface5 {
 //! @cond INTERNAL
@@ -189,6 +186,7 @@ bool operator!=( const solist_iterator<Solist,T>& i, const solist_iterator<Solis
 // Forward type and class definitions
 typedef size_t sokey_t;
 
+
 // Forward list in which elements are sorted in a split-order
 template <typename T, typename Allocator>
 class split_ordered_list
@@ -215,6 +213,10 @@ public:
     // Node that holds the element in a split-ordered list
     struct node : tbb::internal::no_assign
     {
+    private:
+        // for compilers that try to generate default constructors though they are not needed.
+        node();  // VS 2008, 2010, 2012
+    public:
         // Initialize the node with the given order key
         void init(sokey_t order_key) {
             my_order_key = order_key;
@@ -230,7 +232,7 @@ public:
         nodeptr_t atomic_set_next(nodeptr_t new_node, nodeptr_t current_node)
         {
             // Try to change the next pointer on the current element to a new element, only if it still points to the cached next
-            nodeptr_t exchange_node = (nodeptr_t) __TBB_CompareAndSwapW((void *) &my_next, (uintptr_t)new_node, (uintptr_t)current_node);
+            nodeptr_t exchange_node = tbb::internal::as_atomic(my_next).compare_and_swap(new_node, current_node);
 
             if (exchange_node == current_node) // TODO: why this branch?
             {
@@ -271,12 +273,15 @@ public:
         return (pnode);
     }
 
-    // Allocate a new node with the given order key; used to allocate dummy nodes
-    nodeptr_t create_node(sokey_t order_key) {
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    //TODO: try to combine both implementations using poor man forward
+    //TODO: use RAII scoped guard instead of explicit catch
+    // Allocate a new node with the given order key and value
+    nodeptr_t create_node(sokey_t order_key, T &&value) {
         nodeptr_t pnode = my_node_allocator.allocate(1);
 
         __TBB_TRY {
-            new(static_cast<void*>(&pnode->my_element)) T();
+            new(static_cast<void*>(&pnode->my_element)) T(std::move(value));
             pnode->init(order_key);
         } __TBB_CATCH(...) {
             my_node_allocator.deallocate(pnode, 1);
@@ -285,6 +290,14 @@ public:
 
         return (pnode);
     }
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
+    // Allocate a new node with the given order key; used to allocate dummy nodes
+    nodeptr_t create_node(sokey_t order_key) {
+        nodeptr_t pnode = my_node_allocator.allocate(1);
+        pnode->init(order_key);
+        return (pnode);
+    }
 
    split_ordered_list(allocator_type a = allocator_type())
        : my_node_allocator(a), my_element_count(0)
@@ -383,8 +396,8 @@ public:
             return;
         }
 
-        std::swap(my_element_count, other.my_element_count);
-        std::swap(my_head, other.my_head);
+            std::swap(my_element_count, other.my_element_count);
+            std::swap(my_head, other.my_head);
     }
 
     // Split-order list functions
@@ -412,7 +425,7 @@ public:
     }
 
     static sokey_t get_safe_order_key(const raw_const_iterator& it) {
-        if( !it.get_node_ptr() ) return sokey_t(~0U);
+        if( !it.get_node_ptr() )  return ~sokey_t(0);
         return it.get_node_ptr()->get_order_key();
     }
 
@@ -464,7 +477,7 @@ public:
 
     // Erase an element using the allocator
     void destroy_node(nodeptr_t pnode) {
-        my_node_allocator.destroy(pnode);
+        if (!pnode->is_dummy()) my_node_allocator.destroy(pnode);
         my_node_allocator.deallocate(pnode, 1);
     }
 
@@ -484,7 +497,7 @@ public:
         if (inserted_node == pnode)
         {
             // If the insert succeeded, check that the order is correct and increment the element count
-            check_range();
+            check_range(it, next);
             *new_count = __TBB_FetchAndAddW((uintptr_t*)&my_element_count, uintptr_t(1));
             return std::pair<iterator, bool>(iterator(pnode, this), true);
         }
@@ -525,7 +538,7 @@ public:
                 if (inserted_node == dummy_node)
                 {
                     // Insertion succeeded, check the list for order violations
-                    check_range();
+                    check_range(it, where);
                     return raw_iterator(dummy_node);
                 }
                 else
@@ -603,18 +616,29 @@ public:
 
 
 private:
+    //Need to setup private fields of split_ordered_list in move constructor and assignment of concurrent_unordered_base
+    template <typename Traits>
+    friend class concurrent_unordered_base;
 
     // Check the list for order violations
-    void check_range()
+    void check_range( raw_iterator first, raw_iterator last )
     {
 #if TBB_USE_ASSERT
-        for (raw_iterator it = raw_begin(); it != raw_end(); ++it)
+        for (raw_iterator it = first; it != last; ++it)
         {
-            raw_iterator next_iterator = it;
-            ++next_iterator;
+            raw_iterator next = it;
+            ++next;
 
-            __TBB_ASSERT(next_iterator == end() || next_iterator.get_node_ptr()->get_order_key() >= it.get_node_ptr()->get_order_key(), "!!! List order inconsistency !!!");
+            __TBB_ASSERT(next == raw_end() || get_order_key(next) >= get_order_key(it), "!!! List order inconsistency !!!");
         }
+#else
+        tbb::internal::suppress_unused_warning(first, last);
+#endif
+    }
+    void check_range()
+    {
+#if TBB_USE_ASSERT
+        check_range( raw_begin(), raw_end() );
 #endif
     }
 
@@ -628,6 +652,9 @@ template<typename Key, typename Hasher, typename Key_equality>
 class hash_compare
 {
 public:
+    typedef Hasher hasher;
+    typedef Key_equality key_equal;
+
     hash_compare() {}
 
     hash_compare(Hasher a_hasher) : my_hash_object(a_hasher) {}
@@ -646,9 +673,9 @@ public:
     Key_equality my_key_compare_object; // The equality comparator object
 };
 
-#if _MSC_VER
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
 #pragma warning(push)
-#pragma warning(disable: 4127) // warning 4127 -- while (true) has a constant expression in it (for allow_multimapping)
+#pragma warning(disable: 4127) // warning C4127: conditional expression is constant
 #endif
 
 template <typename Traits>
@@ -662,6 +689,8 @@ protected:
     typedef typename Traits::hash_compare hash_compare;
     typedef typename Traits::value_compare value_compare;
     typedef typename Traits::allocator_type allocator_type;
+    typedef typename hash_compare::hasher hasher;
+    typedef typename hash_compare::key_equal key_equal;
     typedef typename allocator_type::pointer pointer;
     typedef typename allocator_type::const_pointer const_pointer;
     typedef typename allocator_type::reference reference;
@@ -681,14 +710,24 @@ protected:
     using Traits::get_key;
     using Traits::allow_multimapping;
 
+    static const size_type initial_bucket_number = 8;                               // Initial number of buckets
 private:
     typedef std::pair<iterator, iterator> pairii_t;
     typedef std::pair<const_iterator, const_iterator> paircc_t;
 
     static size_type const pointers_per_table = sizeof(size_type) * 8;              // One bucket segment per bit
-    static const size_type initial_bucket_number = 8;                               // Initial number of buckets
     static const size_type initial_bucket_load = 4;                                // Initial maximum number of elements per bucket
 
+    struct call_internal_clear_on_exit{
+        concurrent_unordered_base* my_instance;
+        call_internal_clear_on_exit(concurrent_unordered_base* instance) : my_instance(instance) {}
+        void dismiss(){ my_instance = NULL;}
+        ~call_internal_clear_on_exit(){
+            if (my_instance){
+                my_instance->internal_clear();
+            }
+        }
+    };
 protected:
     // Constructors/Destructors
     concurrent_unordered_base(size_type n_of_buckets = initial_bucket_number,
@@ -711,16 +750,101 @@ protected:
     concurrent_unordered_base(const concurrent_unordered_base& right)
         : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator())
     {
+        //FIXME:exception safety seems to be broken here
         internal_init();
         internal_copy(right);
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    concurrent_unordered_base(concurrent_unordered_base&& right)
+        : Traits(right.my_hash_compare), my_solist(right.get_allocator()), my_allocator(right.get_allocator())
+    {
+        internal_init();
+        swap(right);
+    }
+
+    concurrent_unordered_base(concurrent_unordered_base&& right, const allocator_type& a)
+        : Traits(right.my_hash_compare), my_solist(a), my_allocator(a)
+    {
+        call_internal_clear_on_exit clear_buckets_on_exception(this);
+
+        internal_init();
+        if (a == right.get_allocator()){
+            this->swap(right);
+        }else{
+            my_maximum_bucket_size = right.my_maximum_bucket_size;
+            my_number_of_buckets = right.my_number_of_buckets;
+            my_solist.my_element_count = right.my_solist.my_element_count;
+
+            if (! right.my_solist.empty()){
+                nodeptr_t previous_node = my_solist.my_head;
+
+                // Move all elements one by one, including dummy ones
+                for (raw_const_iterator it = ++(right.my_solist.raw_begin()), last = right.my_solist.raw_end(); it != last; ++it)
+                {
+                    const nodeptr_t pnode = it.get_node_ptr();
+                    nodeptr_t node;
+                    if (pnode->is_dummy()) {
+                        node = my_solist.create_node(pnode->get_order_key());
+                        size_type bucket = __TBB_ReverseBits(pnode->get_order_key()) % my_number_of_buckets;
+                        set_bucket(bucket, node);
+                    }else{
+                        node = my_solist.create_node(pnode->get_order_key(), std::move(pnode->my_element));
+                    }
+
+                    previous_node = my_solist.try_insert(previous_node, node, NULL);
+                    __TBB_ASSERT(previous_node != NULL, "Insertion of node failed. Concurrent inserts in constructor ?");
+                }
+                my_solist.check_range();
+            }
+        }
+
+        clear_buckets_on_exception.dismiss();
+    }
+
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
     concurrent_unordered_base& operator=(const concurrent_unordered_base& right) {
         if (this != &right)
             internal_copy(right);
         return (*this);
     }
 
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    concurrent_unordered_base& operator=(concurrent_unordered_base&& other)
+    {
+        if(this != &other){
+            typedef typename tbb::internal::allocator_traits<allocator_type>::propagate_on_container_move_assignment pocma_t;
+            if(pocma_t::value || this->my_allocator == other.my_allocator) {
+                concurrent_unordered_base trash (std::move(*this));
+                swap(other);
+                if (pocma_t::value) {
+                    using std::swap;
+                    //TODO: swapping allocators here may be a problem, replace with single direction moving
+                    swap(this->my_solist.my_node_allocator, other.my_solist.my_node_allocator);
+                    swap(this->my_allocator, other.my_allocator);
+                }
+            } else {
+                concurrent_unordered_base moved_copy(std::move(other),this->my_allocator);
+                this->swap(moved_copy);
+            }
+        }
+        return *this;
+    }
+
+#endif //__TBB_CPP11_RVALUE_REF_PRESENT
+
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! assignment operator from initializer_list
+    concurrent_unordered_base& operator=(std::initializer_list<value_type> il)
+    {
+        this->clear();
+        this->insert(il.begin(),il.end());
+        return (*this);
+    }
+#endif //# __TBB_INITIALIZER_LISTS_PRESENT
+
+
     ~concurrent_unordered_base() {
         // Delete all node segments
         internal_clear();
@@ -821,11 +945,16 @@ public:
                 sokey_t end_key = solist_t::get_safe_order_key(my_end_node);
                 size_t mid_bucket = __TBB_ReverseBits( begin_key + (end_key-begin_key)/2 ) % my_table.my_number_of_buckets;
                 while ( !my_table.is_initialized(mid_bucket) ) mid_bucket = my_table.get_parent(mid_bucket);
-                my_midpoint_node = my_table.my_solist.first_real_iterator(my_table.get_bucket( mid_bucket ));
-                if( my_midpoint_node == my_begin_node )
+                if(__TBB_ReverseBits(mid_bucket) > begin_key) {
+                    // found a dummy_node between begin and end
+                    my_midpoint_node = my_table.my_solist.first_real_iterator(my_table.get_bucket( mid_bucket ));
+                }
+                else {
+                    // didn't find a dummy node between begin and end.
                     my_midpoint_node = my_end_node;
+                }
 #if TBB_USE_ASSERT
-                else {
+                {
                     sokey_t mid_key = solist_t::get_safe_order_key(my_midpoint_node);
                     __TBB_ASSERT( begin_key < mid_key, "my_begin_node is after my_midpoint_node" );
                     __TBB_ASSERT( mid_key <= end_key, "my_midpoint_node is after my_end_node" );
@@ -871,6 +1000,13 @@ public:
             insert(*it);
     }
 
+#if __TBB_INITIALIZER_LISTS_PRESENT
+    //! Insert initializer list
+    void insert(std::initializer_list<value_type> il) {
+        insert(il.begin(), il.end());
+    }
+#endif
+
     iterator unsafe_erase(const_iterator where) {
         return internal_erase(where);
     }
@@ -899,6 +1035,14 @@ public:
     }
 
     // Observers
+    hasher hash_function() const {
+        return my_hash_compare.my_hash_object;
+    }
+
+    key_equal key_eq() const {
+        return my_hash_compare.my_key_compare_object;
+    }
+
     void clear() {
         // Clear list
         my_solist.clear();
@@ -1019,11 +1163,11 @@ public:
     }
 
     const_local_iterator unsafe_cbegin(size_type bucket) const {
-        return ((const self_type *) this)->begin();
+        return ((const self_type *) this)->unsafe_begin(bucket);
     }
 
     const_local_iterator unsafe_cend(size_type bucket) const {
-        return ((const self_type *) this)->end();
+        return ((const self_type *) this)->unsafe_end(bucket);
     }
 
     // Hash policy
@@ -1101,6 +1245,7 @@ private:
         }
     }
 
+    //TODO: why not use std::distance?
     // Hash APIs
     size_type internal_distance(const_iterator first, const_iterator last) const
     {
@@ -1122,7 +1267,7 @@ private:
         if (!is_initialized(bucket))
             init_bucket(bucket);
 
-        size_type new_count;
+        size_type new_count = 0;
         order_key = split_order_key_regular(order_key);
         raw_iterator it = get_bucket(bucket);
         raw_iterator last = my_solist.raw_end();
@@ -1295,8 +1440,8 @@ private:
         // Grow the table by a factor of 2 if possible and needed
         if ( ((float) total_elements / (float) current_size) > my_maximum_bucket_size )
         {
-            // Double the size of the hash only if size has not changed inbetween loads
-            __TBB_CompareAndSwapW((uintptr_t*)&my_number_of_buckets, uintptr_t(2u*current_size), uintptr_t(current_size) );
+            // Double the size of the hash only if size has not changed in between loads
+            my_number_of_buckets.compare_and_swap(2u*current_size, current_size);
             //Simple "my_number_of_buckets.compare_and_swap( current_size<<1, current_size );" does not work for VC8
             //due to overzealous compiler warnings in /Wp64 mode
         }
@@ -1342,7 +1487,7 @@ private:
             raw_iterator * new_segment = my_allocator.allocate(sz);
             std::memset(new_segment, 0, sz*sizeof(raw_iterator));
 
-            if (__TBB_CompareAndSwapW((void *) &my_buckets[segment], (uintptr_t)new_segment, 0) != 0)
+            if (my_buckets[segment].compare_and_swap( new_segment, NULL) != NULL)
                 my_allocator.deallocate(new_segment, sz);
         }
 
@@ -1369,7 +1514,7 @@ private:
 
     // A dummy order key has its original hash value reversed and the last bit unset
     sokey_t split_order_key_dummy(sokey_t order_key) const {
-        return __TBB_ReverseBits(order_key) & ~(0x1);
+        return __TBB_ReverseBits(order_key) & ~sokey_t(0x1);
     }
 
     // Shared variables
@@ -1379,12 +1524,12 @@ private:
     float                                                         my_maximum_bucket_size;     // Maximum size of the bucket
     atomic<raw_iterator*>                                         my_buckets[pointers_per_table]; // The segment table
 };
-#if _MSC_VER
-#pragma warning(pop) // warning 4127 -- while (true) has a constant expression in it
+#if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
+#pragma warning(pop) // warning 4127 is back
 #endif
 
 //! Hash multiplier
-static const size_t hash_multiplier = sizeof(size_t)==4? 2654435769U : 11400714819323198485ULL;
+static const size_t hash_multiplier = tbb::internal::select_size_t_constant<2654435769U, 11400714819323198485ULL>::value;
 } // namespace internal
 //! @endcond
 //! Hasher functions
index 6e7ea56db151bcd9223011425a97014d73b406a9..97da56df75797a7ed4f5410e061ceadf11e77e6e 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__flow_graph_impl_H
@@ -39,6 +31,8 @@ namespace internal {
         enum graph_buffer_policy { rejecting, reserving, queueing, tag_matching };
     }
 
+// -------------- function_body containers ----------------------
+
     //! A functor that takes no input and generates a value of type Output
     template< typename Output >
     class source_body : tbb::internal::no_assign {
@@ -46,22 +40,31 @@ namespace internal {
         virtual ~source_body() {}
         virtual bool operator()(Output &output) = 0;
         virtual source_body* clone() = 0;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        virtual void reset_body() = 0;
+#endif
     };
-    
+
     //! The leaf for source_body
     template< typename Output, typename Body>
     class source_body_leaf : public source_body<Output> {
     public:
         source_body_leaf( const Body &_body ) : body(_body), init_body(_body) { }
         /*override*/ bool operator()(Output &output) { return body( output ); }
-        /*override*/ source_body_leaf* clone() { 
-            return new source_body_leaf< Output, Body >(init_body); 
+        /*override*/ source_body_leaf* clone() {
+            return new source_body_leaf< Output, Body >(init_body);
+        }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void reset_body() {
+            body = init_body;
         }
+#endif
+        Body get_body() { return body; }
     private:
         Body body;
         Body init_body;
     };
-    
+
     //! A functor that takes an Input and generates an Output
     template< typename Input, typename Output >
     class function_body : tbb::internal::no_assign {
@@ -69,14 +72,22 @@ namespace internal {
         virtual ~function_body() {}
         virtual Output operator()(const Input &input) = 0;
         virtual function_body* clone() = 0;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        virtual void reset_body() = 0;
+#endif
     };
-    
+
     //! the leaf for function_body
     template <typename Input, typename Output, typename B>
     class function_body_leaf : public function_body< Input, Output > {
     public:
         function_body_leaf( const B &_body ) : body(_body), init_body(_body) { }
         Output operator()(const Input &i) { return body(i); }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void reset_body() {
+            body = init_body;
+        }
+#endif
         B get_body() { return body; }
         /*override*/ function_body_leaf* clone() {
             return new function_body_leaf< Input, Output, B >(init_body);
@@ -85,217 +96,273 @@ namespace internal {
         B body;
         B init_body;
     };
-    
+
     //! the leaf for function_body specialized for Input and output of continue_msg
     template <typename B>
     class function_body_leaf< continue_msg, continue_msg, B> : public function_body< continue_msg, continue_msg > {
     public:
         function_body_leaf( const B &_body ) : body(_body), init_body(_body) { }
-        continue_msg operator()( const continue_msg &i ) { 
-            body(i); 
-            return i; 
+        continue_msg operator()( const continue_msg &i ) {
+            body(i);
+            return i;
         }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void reset_body() {
+            body = init_body;
+        }
+#endif
         B get_body() { return body; }
         /*override*/ function_body_leaf* clone() {
            return new function_body_leaf< continue_msg, continue_msg, B >(init_body);
-        }    
+        }
     private:
         B body;
         B init_body;
     };
-    
+
     //! the leaf for function_body specialized for Output of continue_msg
     template <typename Input, typename B>
     class function_body_leaf< Input, continue_msg, B> : public function_body< Input, continue_msg > {
     public:
         function_body_leaf( const B &_body ) : body(_body), init_body(_body) { }
-        continue_msg operator()(const Input &i) { 
-            body(i); 
+        continue_msg operator()(const Input &i) {
+            body(i);
             return continue_msg();
         }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void reset_body() {
+            body = init_body;
+        }
+#endif
         B get_body() { return body; }
         /*override*/ function_body_leaf* clone() {
             return new function_body_leaf< Input, continue_msg, B >(init_body);
-        }    
+        }
     private:
         B body;
         B init_body;
     };
-    
+
     //! the leaf for function_body specialized for Input of continue_msg
     template <typename Output, typename B>
     class function_body_leaf< continue_msg, Output, B > : public function_body< continue_msg, Output > {
     public:
         function_body_leaf( const B &_body ) : body(_body), init_body(_body) { }
-        Output operator()(const continue_msg &i) { 
-            return body(i); 
+        Output operator()(const continue_msg &i) {
+            return body(i);
+        }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void reset_body() {
+            body = init_body;
         }
+#endif
         B get_body() { return body; }
         /*override*/ function_body_leaf* clone() {
             return new function_body_leaf< continue_msg, Output, B >(init_body);
-        }    
+        }
     private:
         B body;
         B init_body;
     };
 
-# if TBB_PREVIEW_GRAPH_NODES
     //! function_body that takes an Input and a set of output ports
     template<typename Input, typename OutputSet>
-    class multioutput_function_body {
+    class multifunction_body : tbb::internal::no_assign {
     public:
-        virtual ~multioutput_function_body () {}
+        virtual ~multifunction_body () {}
         virtual void operator()(const Input &/* input*/, OutputSet &/*oset*/) = 0;
-        virtual multioutput_function_body* clone() = 0;
+        virtual multifunction_body* clone() = 0;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        virtual void reset_body() = 0;
+#endif
     };
 
-    //! leaf for multi-output function.  OutputSet can be a std::tuple or a vector.
+    //! leaf for multifunction.  OutputSet can be a std::tuple or a vector.
     template<typename Input, typename OutputSet, typename B>
-    class multioutput_function_body_leaf : public multioutput_function_body<Input, OutputSet> {
+    class multifunction_body_leaf : public multifunction_body<Input, OutputSet> {
     public:
-        multioutput_function_body_leaf(const B &_body) : body(_body), init_body(_body) { }
+        multifunction_body_leaf(const B &_body) : body(_body), init_body(_body) { }
         void operator()(const Input &input, OutputSet &oset) {
-            body(input, oset); // body should explicitly put() to one or more of oset.
+            body(input, oset); // body may explicitly put() to one or more of oset.
         }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void reset_body() {
+            body = init_body;
+        }
+#endif
         B get_body() { return body; }
-        /*override*/ multioutput_function_body_leaf* clone() {
-            return new multioutput_function_body_leaf<Input, OutputSet,B>(init_body);
+        /*override*/ multifunction_body_leaf* clone() {
+            return new multifunction_body_leaf<Input, OutputSet,B>(init_body);
         }
     private:
         B body;
         B init_body;
     };
-#endif  // TBB_PREVIEW_GRAPH_NODES
-    
-    //! A task that calls a node's forward function
+
+// --------------------------- end of function_body containers ------------------------
+
+// --------------------------- node task bodies ---------------------------------------
+
+    //! A task that calls a node's forward_task function
     template< typename NodeType >
-    class forward_task : public task {
-    
+    class forward_task_bypass : public task {
+
         NodeType &my_node;
-    
+
     public:
-    
-        forward_task( NodeType &n ) : my_node(n) {}
-    
+
+        forward_task_bypass( NodeType &n ) : my_node(n) {}
+
         task *execute() {
-            my_node.forward();
-            return NULL;
+            task * new_task = my_node.forward_task();
+            if (new_task == SUCCESSFULLY_ENQUEUED) new_task = NULL;
+            return new_task;
         }
     };
-    
-    //! A task that calls a node's apply_body function, passing in an input of type Input
+
+    //! A task that calls a node's apply_body_bypass function, passing in an input of type Input
+    //  return the task* unless it is SUCCESSFULLY_ENQUEUED, in which case return NULL
     template< typename NodeType, typename Input >
-    class apply_body_task : public task {
-    
+    class apply_body_task_bypass : public task {
+
         NodeType &my_node;
         Input my_input;
-        
+
     public:
-        
-        apply_body_task( NodeType &n, const Input &i ) : my_node(n), my_input(i) {}
-        
+
+        apply_body_task_bypass( NodeType &n, const Input &i ) : my_node(n), my_input(i) {}
+
         task *execute() {
-            my_node.apply_body( my_input );
-            return NULL;
+            task * next_task = my_node.apply_body_bypass( my_input );
+            if(next_task == SUCCESSFULLY_ENQUEUED) next_task = NULL;
+            return next_task;
         }
     };
-    
+
     //! A task that calls a node's apply_body function with no input
     template< typename NodeType >
-    class source_task : public task {
-    
+    class source_task_bypass : public task {
+
         NodeType &my_node;
-    
+
     public:
-    
-        source_task( NodeType &n ) : my_node(n) {}
-    
+
+        source_task_bypass( NodeType &n ) : my_node(n) {}
+
         task *execute() {
-            my_node.apply_body( );
-            return NULL;
+            task *new_task = my_node.apply_body_bypass( );
+            if(new_task == SUCCESSFULLY_ENQUEUED) return NULL;
+            return new_task;
         }
     };
-    
+
+// ------------------------ end of node task bodies -----------------------------------
+
     //! An empty functor that takes an Input and returns a default constructed Output
     template< typename Input, typename Output >
     struct empty_body {
-       Output operator()( const Input & ) const { return Output(); } 
+       Output operator()( const Input & ) const { return Output(); }
     };
-    
-    //! A node_cache maintains a std::queue of elements of type T.  Each operation is protected by a lock. 
+
+    //! A node_cache maintains a std::queue of elements of type T.  Each operation is protected by a lock.
     template< typename T, typename M=spin_mutex >
     class node_cache {
         public:
-    
+
         typedef size_t size_type;
-        
+
         bool empty() {
             typename my_mutex_type::scoped_lock lock( my_mutex );
             return internal_empty();
         }
-    
+
         void add( T &n ) {
             typename my_mutex_type::scoped_lock lock( my_mutex );
             internal_push(n);
         }
-    
+
         void remove( T &n ) {
             typename my_mutex_type::scoped_lock lock( my_mutex );
             for ( size_t i = internal_size(); i != 0; --i ) {
                 T &s = internal_pop();
-                if ( &s != &n ) {
-                    internal_push(s);
-                }
+                if ( &s == &n )  return;  // only remove one predecessor per request
+                internal_push(s);
             }
         }
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<T *> predecessor_vector_type;
+        void internal_add_built_predecessor( T &n ) {
+            typename my_mutex_type::scoped_lock lock( my_mutex );
+            my_built_predecessors.add_edge(n);
+        }
+
+        void internal_delete_built_predecessor( T &n ) {
+            typename my_mutex_type::scoped_lock lock( my_mutex );
+            my_built_predecessors.delete_edge(n);
+        }
+
+        void copy_predecessors( predecessor_vector_type &v) {
+            typename my_mutex_type::scoped_lock lock( my_mutex );
+            my_built_predecessors.copy_edges(v);
+        }
+
+        size_t predecessor_count() {
+            typename my_mutex_type::scoped_lock lock(my_mutex);
+            return (size_t)(my_built_predecessors.edge_count());
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */ 
+
     protected:
-    
+
         typedef M my_mutex_type;
         my_mutex_type my_mutex;
         std::queue< T * > my_q;
-    
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        edge_container<T> my_built_predecessors;
+#endif
+
         // Assumes lock is held
         inline bool internal_empty( )  {
             return my_q.empty();
         }
-    
+
         // Assumes lock is held
         inline size_type internal_size( )  {
-            return my_q.size(); 
+            return my_q.size();
         }
-    
+
         // Assumes lock is held
         inline void internal_push( T &n )  {
             my_q.push(&n);
         }
-    
+
         // Assumes lock is held
         inline T &internal_pop() {
             T *v = my_q.front();
             my_q.pop();
             return *v;
         }
-    
+
     };
-    
+
     //! A cache of predecessors that only supports try_get
     template< typename T, typename M=spin_mutex >
     class predecessor_cache : public node_cache< sender<T>, M > {
-        public:
+    public:
         typedef M my_mutex_type;
-        typedef T output_type; 
+        typedef T output_type;
         typedef sender<output_type> predecessor_type;
         typedef receiver<output_type> successor_type;
-    
+
         predecessor_cache( ) : my_owner( NULL ) { }
-        
+
         void set_owner( successor_type *owner ) { my_owner = owner; }
-        
+
         bool get_item( output_type &v ) {
-        
+
             bool msg = false;
-        
+
             do {
                 predecessor_type *src;
                 {
@@ -305,13 +372,13 @@ namespace internal {
                     }
                     src = &this->internal_pop();
                 }
-        
+
                 // Try to get from this sender
                 msg = src->try_get( v );
-        
+
                 if (msg == false) {
                     // Relinquish ownership of the edge
-                    if ( my_owner) 
+                    if ( my_owner)
                         src->register_successor( *my_owner );
                 } else {
                     // Retain ownership of the edge
@@ -320,38 +387,60 @@ namespace internal {
             } while ( msg == false );
             return msg;
         }
-    
+
+        void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            if(my_owner) {
+                for(;;) {
+                    predecessor_type *src;
+                    {
+                        if(this->internal_empty()) break;
+                        src = &this->internal_pop();
+                    }
+                        src->register_successor( *my_owner);
+                }
+            }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            if (f&rf_extract && my_owner) 
+                my_built_predecessors.receiver_extract(*my_owner);
+            __TBB_ASSERT(!(f&rf_extract) || this->internal_empty(), "predecessor cache not empty");
+#endif
+        }
+
     protected:
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        using node_cache< sender<T>, M >::my_built_predecessors;
+#endif
         successor_type *my_owner;
     };
-    
+
     //! An cache of predecessors that supports requests and reservations
     template< typename T, typename M=spin_mutex >
     class reservable_predecessor_cache : public predecessor_cache< T, M > {
     public:
         typedef M my_mutex_type;
-        typedef T output_type; 
+        typedef T output_type;
         typedef sender<T> predecessor_type;
         typedef receiver<T> successor_type;
-        
+
         reservable_predecessor_cache( ) : reserved_src(NULL) { }
-        
-        bool 
+
+        bool
         try_reserve( output_type &v ) {
             bool msg = false;
-        
+
             do {
                 {
                     typename my_mutex_type::scoped_lock lock(this->my_mutex);
-                    if ( reserved_src || this->internal_empty() ) 
+                    if ( reserved_src || this->internal_empty() )
                         return false;
-        
+
                     reserved_src = &this->internal_pop();
                 }
-        
+
                 // Try to get from this sender
                 msg = reserved_src->try_reserve( v );
-        
+
                 if (msg == false) {
                     typename my_mutex_type::scoped_lock lock(this->my_mutex);
                     // Relinquish ownership of the edge
@@ -362,110 +451,185 @@ namespace internal {
                     this->add( *reserved_src );
                 }
             } while ( msg == false );
-        
+
             return msg;
         }
-        
-        bool 
+
+        bool
         try_release( ) {
             reserved_src->try_release( );
             reserved_src = NULL;
             return true;
         }
-        
-        bool 
+
+        bool
         try_consume( ) {
             reserved_src->try_consume( );
             reserved_src = NULL;
             return true;
         }
-    
+
+        void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            reserved_src = NULL;
+            predecessor_cache<T,M>::reset(__TBB_PFG_RESET_ARG(f));
+        }
+
     private:
         predecessor_type *reserved_src;
     };
-    
-    
-    //! An abstract cache of succesors
+
+
+    //! An abstract cache of successors
     template<typename T, typename M=spin_rw_mutex >
     class successor_cache : tbb::internal::no_copy {
     protected:
-        
+
         typedef M my_mutex_type;
         my_mutex_type my_mutex;
-        
-        typedef std::list< receiver<T> * > my_successors_type;
+
+        typedef receiver<T> *pointer_type;
+        typedef std::list< pointer_type > my_successors_type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        edge_container<receiver<T> > my_built_successors;
+#endif
         my_successors_type my_successors;
-        
+
         sender<T> *my_owner;
-        
+
     public:
-        
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<pointer_type> successor_vector_type;
+        void internal_add_built_successor( receiver<T> &r) {
+            typename my_mutex_type::scoped_lock l(my_mutex, true);
+            my_built_successors.add_edge( r );
+        }
+
+        void internal_delete_built_successor( receiver<T> &r) {
+            typename my_mutex_type::scoped_lock l(my_mutex, true);
+            my_built_successors.delete_edge(r);
+        }
+
+        void copy_successors( successor_vector_type &v) {
+            typename my_mutex_type::scoped_lock l(my_mutex, false);
+            my_built_successors.copy_edges(v);
+        }
+
+        size_t successor_count() {
+            typename my_mutex_type::scoped_lock l(my_mutex,false);
+            return my_built_successors.edge_count();
+        }
+
+        void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            if (f&rf_extract && my_owner) 
+                my_built_successors.sender_extract(*my_owner);
+        }
+#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
         successor_cache( ) : my_owner(NULL) {}
-        
+
         void set_owner( sender<T> *owner ) { my_owner = owner; }
-        
+
         virtual ~successor_cache() {}
-        
+
         void register_successor( receiver<T> &r ) {
             typename my_mutex_type::scoped_lock l(my_mutex, true);
-            my_successors.push_back( &r ); 
+            my_successors.push_back( &r );
         }
-    
+
         void remove_successor( receiver<T> &r ) {
             typename my_mutex_type::scoped_lock l(my_mutex, true);
             for ( typename my_successors_type::iterator i = my_successors.begin();
-                  i != my_successors.end(); ++i ) { 
-                if ( *i == & r ) { 
+                  i != my_successors.end(); ++i ) {
+                if ( *i == & r ) {
                     my_successors.erase(i);
                     break;
                 }
             }
         }
-        
-        bool empty() { 
+
+        bool empty() {
             typename my_mutex_type::scoped_lock l(my_mutex, false);
-            return my_successors.empty(); 
+            return my_successors.empty();
+        }
+
+        void clear() {
+            my_successors.clear();
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            my_built_successors.clear();
+#endif
         }
-        
-        virtual bool try_put( const T &t ) = 0; 
+
+        virtual task * try_put_task( const T &t ) = 0;
      };
-    
-    //! An abstract cache of succesors, specialized to continue_msg
+
+    //! An abstract cache of successors, specialized to continue_msg
     template<>
     class successor_cache< continue_msg > : tbb::internal::no_copy {
     protected:
-        
+
         typedef spin_rw_mutex my_mutex_type;
         my_mutex_type my_mutex;
-        
-        typedef std::list< receiver<continue_msg> * > my_successors_type;
+
+        typedef receiver<continue_msg> *pointer_type;
+        typedef std::list< pointer_type > my_successors_type;
         my_successors_type my_successors;
-        
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        edge_container<receiver<continue_msg> > my_built_successors;
+#endif
+
         sender<continue_msg> *my_owner;
-        
+
     public:
-        
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<pointer_type> successor_vector_type;
+        void internal_add_built_successor( receiver<continue_msg> &r) {
+            my_mutex_type::scoped_lock l(my_mutex, true);
+            my_built_successors.add_edge( r );
+        }
+
+        void internal_delete_built_successor( receiver<continue_msg> &r) {
+            my_mutex_type::scoped_lock l(my_mutex, true);
+            my_built_successors.delete_edge(r);
+        }
+
+        void copy_successors( successor_vector_type &v) {
+            my_mutex_type::scoped_lock l(my_mutex, false);
+            my_built_successors.copy_edges(v);
+        }
+
+        size_t successor_count() {
+            my_mutex_type::scoped_lock l(my_mutex,false);
+            return my_built_successors.edge_count();
+        }
+
+        void reset( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            if (f&rf_extract && my_owner) 
+                my_built_successors.sender_extract(*my_owner);
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
         successor_cache( ) : my_owner(NULL) {}
-        
+
         void set_owner( sender<continue_msg> *owner ) { my_owner = owner; }
-        
+
         virtual ~successor_cache() {}
-        
+
         void register_successor( receiver<continue_msg> &r ) {
             my_mutex_type::scoped_lock l(my_mutex, true);
-            my_successors.push_back( &r ); 
-            if ( my_owner ) {
-                continue_receiver *cr = dynamic_cast< continue_receiver * >(&r);
-                if ( cr ) 
-                    cr->register_predecessor( *my_owner );
+            my_successors.push_back( &r );
+            if ( my_owner && r.is_continue_receiver() ) {
+                r.register_predecessor( *my_owner );
             }
         }
-        
+
         void remove_successor( receiver<continue_msg> &r ) {
             my_mutex_type::scoped_lock l(my_mutex, true);
             for ( my_successors_type::iterator i = my_successors.begin();
-                  i != my_successors.end(); ++i ) { 
-                if ( *i == & r ) { 
+                  i != my_successors.end(); ++i ) {
+                if ( *i == & r ) {
+                    // TODO: Check if we need to test for continue_receiver before
+                    // removing from r.
                     if ( my_owner )
                         r.remove_predecessor( *my_owner );
                     my_successors.erase(i);
@@ -473,50 +637,60 @@ namespace internal {
                 }
             }
         }
-    
-        bool empty() { 
+
+        bool empty() {
             my_mutex_type::scoped_lock l(my_mutex, false);
-            return my_successors.empty(); 
+            return my_successors.empty();
+        }
+
+        void clear() {
+            my_successors.clear();
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            my_built_successors.clear();
+#endif
         }
-    
-        virtual bool try_put( const continue_msg &t ) = 0; 
-        
+
+        virtual task * try_put_task( const continue_msg &t ) = 0;
+
      };
-    
+
     //! A cache of successors that are broadcast to
     template<typename T, typename M=spin_rw_mutex>
     class broadcast_cache : public successor_cache<T, M> {
         typedef M my_mutex_type;
         typedef std::list< receiver<T> * > my_successors_type;
-        
+
     public:
-        
+
         broadcast_cache( ) {}
-        
-        bool try_put( const T &t ) {
-            bool msg = false;
-            bool upgraded = false;
-            typename my_mutex_type::scoped_lock l(this->my_mutex, false);
+
+        // as above, but call try_put_task instead, and return the last task we received (if any)
+        /*override*/ task * try_put_task( const T &t ) {
+            task * last_task = NULL;
+            bool upgraded = true;
+            typename my_mutex_type::scoped_lock l(this->my_mutex, upgraded);
             typename my_successors_type::iterator i = this->my_successors.begin();
             while ( i != this->my_successors.end() ) {
-               if ( (*i)->try_put( t ) == true ) {
-                   ++i;
-                   msg = true;
-               } else {
-                  if ( (*i)->register_predecessor(*this->my_owner) ) {
-                      if (!upgraded) {
-                          l.upgrade_to_writer();
-                          upgraded = true;
-                      }
-                      i = this->my_successors.erase(i);
-                  }
-                  else {
-                      ++i;
-                  }
-               }
+                task *new_task = (*i)->try_put_task(t);
+                last_task = combine_tasks(last_task, new_task);  // enqueue if necessary
+                if(new_task) {
+                    ++i;
+                }
+                else {  // failed
+                    if ( (*i)->register_predecessor(*this->my_owner) ) {
+                        if (!upgraded) {
+                            l.upgrade_to_writer();
+                            upgraded = true;
+                        }
+                        i = this->my_successors.erase(i);
+                    } else {
+                        ++i;
+                    }
+                }
             }
-            return msg;
+            return last_task;
         }
+
     };
 
     //! A cache of successors that are put in a round-robin fashion
@@ -525,57 +699,58 @@ namespace internal {
         typedef size_t size_type;
         typedef M my_mutex_type;
         typedef std::list< receiver<T> * > my_successors_type;
-    
+
     public:
-        
+
         round_robin_cache( ) {}
-        
+
         size_type size() {
             typename my_mutex_type::scoped_lock l(this->my_mutex, false);
             return this->my_successors.size();
         }
-        
-        bool try_put( const T &t ) {
-            bool upgraded = false;
-            typename my_mutex_type::scoped_lock l(this->my_mutex, false);
+
+        /*override*/task *try_put_task( const T &t ) {
+            bool upgraded = true;
+            typename my_mutex_type::scoped_lock l(this->my_mutex, upgraded);
             typename my_successors_type::iterator i = this->my_successors.begin();
             while ( i != this->my_successors.end() ) {
-               if ( (*i)->try_put( t ) ) {
-                   return true;
-               } else {
-                  if ( (*i)->register_predecessor(*this->my_owner) ) {
-                      if (!upgraded) {
-                          l.upgrade_to_writer();
-                          upgraded = true;
-                      }
-                      i = this->my_successors.erase(i);
-                  }
-                  else {
-                      ++i;
-                  }
-               }
+                task *new_task = (*i)->try_put_task(t);
+                if ( new_task ) {
+                    return new_task;
+                } else {
+                   if ( (*i)->register_predecessor(*this->my_owner) ) {
+                       if (!upgraded) {
+                           l.upgrade_to_writer();
+                           upgraded = true;
+                       }
+                       i = this->my_successors.erase(i);
+                   }
+                   else {
+                       ++i;
+                   }
+                }
             }
-            return false;
+            return NULL;
         }
     };
-    
+
     template<typename T>
     class decrementer : public continue_receiver, tbb::internal::no_copy {
-        
+
         T *my_node;
-        
-        void execute() {
-            my_node->decrement_counter();
+
+        task *execute() {
+            return my_node->decrement_counter();
         }
-        
+
     public:
-       
+
         typedef continue_msg input_type;
         typedef continue_msg output_type;
         decrementer( int number_of_predecessors = 0 ) : continue_receiver( number_of_predecessors ) { }
         void set_owner( T *node ) { my_node = node; }
     };
-    
+
 }
 
 #endif // __TBB__flow_graph_impl_H
diff --git a/dependencies64/tbb/include/tbb/internal/_flow_graph_indexer_impl.h b/dependencies64/tbb/include/tbb/internal/_flow_graph_indexer_impl.h
new file mode 100644 (file)
index 0000000..947e1d4
--- /dev/null
@@ -0,0 +1,453 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB__flow_graph_indexer_impl_H
+#define __TBB__flow_graph_indexer_impl_H
+
+#ifndef __TBB_flow_graph_H
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#include "tbb/internal/_flow_graph_types_impl.h"
+
+namespace internal {
+
+    // Output of the indexer_node is a tbb::flow::tagged_msg, and will be of
+    // the form  tagged_msg<tag, result>
+    // where the value of tag will indicate which result was put to the
+    // successor.  
+    
+    template<typename IndexerNodeBaseType, typename T, size_t K>
+    task* do_try_put(const T &v, void *p) {
+        typename IndexerNodeBaseType::output_type o(K, v);
+        return reinterpret_cast<IndexerNodeBaseType *>(p)->try_put_task(&o);
+    }
+
+    template<typename TupleTypes,int N>
+    struct indexer_helper {
+        template<typename IndexerNodeBaseType, typename PortTuple>
+        static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) {
+            typedef typename tuple_element<N-1, TupleTypes>::type T;
+            task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, N-1>;
+            tbb::flow::get<N-1>(my_input).set_up(p, indexer_node_put_task);
+            indexer_helper<TupleTypes,N-1>::template set_indexer_node_pointer<IndexerNodeBaseType,PortTuple>(my_input, p);
+        }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        template<typename InputTuple>
+        static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
+            join_helper<N-1>::reset_inputs(my_input, f);
+            tbb::flow::get<N-1>(my_input).reset_receiver(f);
+        }
+#endif
+    };
+
+    template<typename TupleTypes>
+    struct indexer_helper<TupleTypes,1> {
+        template<typename IndexerNodeBaseType, typename PortTuple>
+        static inline void set_indexer_node_pointer(PortTuple &my_input, IndexerNodeBaseType *p) {
+            typedef typename tuple_element<0, TupleTypes>::type T;
+            task *(*indexer_node_put_task)(const T&, void *) = do_try_put<IndexerNodeBaseType, T, 0>;
+            tbb::flow::get<0>(my_input).set_up(p, indexer_node_put_task);
+        }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        template<typename InputTuple>
+        static inline void reset_inputs(InputTuple &my_input, reset_flags f) {
+            tbb::flow::get<0>(my_input).reset_receiver(f);
+        }
+#endif
+    };
+
+    template<typename T>
+    class indexer_input_port : public receiver<T> {
+    private:
+        void* my_indexer_ptr;
+        typedef task* (* forward_function_ptr)(T const &, void* );
+        forward_function_ptr my_try_put_task;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        spin_mutex my_pred_mutex;
+        edge_container<sender<T> > my_built_predecessors;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+    public:
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        indexer_input_port() : my_pred_mutex() {}
+        indexer_input_port( const indexer_input_port & /*other*/ ) : receiver<T>(), my_pred_mutex() {
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+        void set_up(void *p, forward_function_ptr f) {
+                my_indexer_ptr = p;
+                my_try_put_task = f;
+            }
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<sender<T> *> predecessor_vector_type;
+        /*override*/size_t predecessor_count() {
+            spin_mutex::scoped_lock l(my_pred_mutex);
+            return my_built_predecessors.edge_count();
+        }
+        /*override*/void internal_add_built_predecessor(sender<T> &p) {
+            spin_mutex::scoped_lock l(my_pred_mutex);
+            my_built_predecessors.add_edge(p);
+        }
+        /*override*/void internal_delete_built_predecessor(sender<T> &p) {
+            spin_mutex::scoped_lock l(my_pred_mutex);
+            my_built_predecessors.delete_edge(p);
+        }
+        /*override*/void copy_predecessors( predecessor_vector_type &v) {
+            spin_mutex::scoped_lock l(my_pred_mutex);
+            return my_built_predecessors.copy_edges(v);
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+    protected:
+        template< typename R, typename B > friend class run_and_put_task;
+        template<typename X, typename Y> friend class internal::broadcast_cache;
+        template<typename X, typename Y> friend class internal::round_robin_cache;
+        task *try_put_task(const T &v) {
+            return my_try_put_task(v, my_indexer_ptr);
+        }
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    public:
+        /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) {
+            if(f&rf_extract) my_built_predecessors.receiver_extract(*this);
+        }
+#else
+        /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { }
+#endif
+
+    };
+
+    template<typename InputTuple, typename OutputType, typename StructTypes>
+    class indexer_node_FE {
+    public:
+        static const int N = tbb::flow::tuple_size<InputTuple>::value;
+        typedef OutputType output_type;
+        typedef InputTuple input_type;
+
+        input_type &input_ports() { return my_inputs; }
+    protected:
+        input_type my_inputs;
+    };
+
+    //! indexer_node_base
+    template<typename InputTuple, typename OutputType, typename StructTypes>
+    class indexer_node_base : public graph_node, public indexer_node_FE<InputTuple, OutputType,StructTypes>,
+                           public sender<OutputType> {
+    protected:
+       using graph_node::my_graph;
+    public:
+        static const size_t N = tbb::flow::tuple_size<InputTuple>::value;
+        typedef OutputType output_type;
+        typedef StructTypes tuple_types;
+        typedef receiver<output_type> successor_type;
+        typedef indexer_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<successor_type *> successor_vector_type;
+#endif
+
+    private:
+        // ----------- Aggregator ------------
+        enum op_type { reg_succ, rem_succ, try__put_task
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            , add_blt_succ, del_blt_succ,
+             blt_succ_cnt, blt_succ_cpy
+#endif
+        };
+        enum op_stat {WAIT=0, SUCCEEDED, FAILED};
+        typedef indexer_node_base<InputTuple,output_type,StructTypes> my_class;
+
+        class indexer_node_base_operation : public aggregated_operation<indexer_node_base_operation> {
+        public:
+            char type;
+            union {
+                output_type const *my_arg;
+                successor_type *my_succ;
+                task *bypass_t;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                size_t cnt_val;
+                successor_vector_type *succv;
+#endif
+            };
+            indexer_node_base_operation(const output_type* e, op_type t) :
+                type(char(t)), my_arg(e) {}
+            indexer_node_base_operation(const successor_type &s, op_type t) : type(char(t)), 
+                my_succ(const_cast<successor_type *>(&s)) {}
+            indexer_node_base_operation(op_type t) : type(char(t)) {}
+        };
+
+        typedef internal::aggregating_functor<my_class, indexer_node_base_operation> my_handler;
+        friend class internal::aggregating_functor<my_class, indexer_node_base_operation>;
+        aggregator<my_handler, indexer_node_base_operation> my_aggregator;
+
+        void handle_operations(indexer_node_base_operation* op_list) {
+            indexer_node_base_operation *current;
+            while(op_list) {
+                current = op_list;
+                op_list = op_list->next;
+                switch(current->type) {
+
+                case reg_succ:
+                    my_successors.register_successor(*(current->my_succ));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+
+                case rem_succ:
+                    my_successors.remove_successor(*(current->my_succ));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case try__put_task: {
+                        current->bypass_t = my_successors.try_put_task(*(current->my_arg));
+                        __TBB_store_with_release(current->status, SUCCEEDED);  // return of try_put_task actual return value
+                    }
+                    break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                case add_blt_succ:
+                    my_successors.internal_add_built_successor(*(current->my_succ));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case del_blt_succ:
+                    my_successors.internal_delete_built_successor(*(current->my_succ));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_succ_cnt:
+                    current->cnt_val = my_successors.successor_count();
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_succ_cpy:
+                    my_successors.copy_successors(*(current->succv));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+                }
+            }
+        }
+        // ---------- end aggregator -----------
+    public:
+        indexer_node_base(graph& g) : graph_node(g), input_ports_type() {
+            indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this);
+            my_successors.set_owner(this);
+            my_aggregator.initialize_handler(my_handler(this));
+        }
+
+        indexer_node_base(const indexer_node_base& other) : graph_node(other.my_graph), input_ports_type(), sender<output_type>() {
+            indexer_helper<StructTypes,N>::set_indexer_node_pointer(this->my_inputs, this);
+            my_successors.set_owner(this);
+            my_aggregator.initialize_handler(my_handler(this));
+        }
+
+        bool register_successor(successor_type &r) {
+            indexer_node_base_operation op_data(r, reg_succ);
+            my_aggregator.execute(&op_data);
+            return op_data.status == SUCCEEDED;
+        }
+
+        bool remove_successor( successor_type &r) {
+            indexer_node_base_operation op_data(r, rem_succ);
+            my_aggregator.execute(&op_data);
+            return op_data.status == SUCCEEDED;
+        }
+
+        task * try_put_task(output_type const *v) {
+            indexer_node_base_operation op_data(v, try__put_task);
+            my_aggregator.execute(&op_data);
+            return op_data.bypass_t;
+        }
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        void internal_add_built_successor( successor_type &r) {
+            indexer_node_base_operation op_data(r, add_blt_succ);
+            my_aggregator.execute(&op_data);
+        }
+
+        void internal_delete_built_successor( successor_type &r) {
+            indexer_node_base_operation op_data(r, del_blt_succ);
+            my_aggregator.execute(&op_data);
+        }
+
+        size_t successor_count() {
+            indexer_node_base_operation op_data(blt_succ_cnt);
+            my_aggregator.execute(&op_data);
+            return op_data.cnt_val;
+        }
+
+        void copy_successors( successor_vector_type &v) {
+            indexer_node_base_operation op_data(blt_succ_cpy);
+            op_data.succv = &v;
+            my_aggregator.execute(&op_data);
+        } 
+#endif /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+    protected:
+        /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) {
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            my_successors.reset(f);
+            indexer_helper<StructTypes,N>::reset_inputs(this->my_inputs, f);
+#endif
+        }
+
+    private:
+        broadcast_cache<output_type, null_rw_mutex> my_successors;
+    };  //indexer_node_base
+
+
+    template<int N, typename InputTuple> struct input_types;
+
+    template<typename InputTuple>
+    struct input_types<1, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename internal::tagged_msg<size_t, first_type > type;
+    };
+
+    template<typename InputTuple>
+    struct input_types<2, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type> type;
+    };
+
+    template<typename InputTuple>
+    struct input_types<3, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type> type;
+    };
+    
+    template<typename InputTuple>
+    struct input_types<4, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type> type;
+    };
+    
+    template<typename InputTuple>
+    struct input_types<5, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename tuple_element<4, InputTuple>::type fifth_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type, fifth_type> type;
+    };
+    
+    template<typename InputTuple>
+    struct input_types<6, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename tuple_element<4, InputTuple>::type fifth_type;
+        typedef typename tuple_element<5, InputTuple>::type sixth_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type, fifth_type, sixth_type> type;
+    };
+    
+    template<typename InputTuple>
+    struct input_types<7, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename tuple_element<4, InputTuple>::type fifth_type;
+        typedef typename tuple_element<5, InputTuple>::type sixth_type;
+        typedef typename tuple_element<6, InputTuple>::type seventh_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type, fifth_type, sixth_type,
+                                                      seventh_type> type;
+    };
+
+
+    template<typename InputTuple>
+    struct input_types<8, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename tuple_element<4, InputTuple>::type fifth_type;
+        typedef typename tuple_element<5, InputTuple>::type sixth_type;
+        typedef typename tuple_element<6, InputTuple>::type seventh_type;
+        typedef typename tuple_element<7, InputTuple>::type eighth_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type, fifth_type, sixth_type,
+                                                      seventh_type, eighth_type> type;
+    };
+
+    template<typename InputTuple>
+    struct input_types<9, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename tuple_element<4, InputTuple>::type fifth_type;
+        typedef typename tuple_element<5, InputTuple>::type sixth_type;
+        typedef typename tuple_element<6, InputTuple>::type seventh_type;
+        typedef typename tuple_element<7, InputTuple>::type eighth_type;
+        typedef typename tuple_element<8, InputTuple>::type nineth_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type, fifth_type, sixth_type,
+                                                      seventh_type, eighth_type, nineth_type> type;
+    };
+
+    template<typename InputTuple>
+    struct input_types<10, InputTuple> {
+        typedef typename tuple_element<0, InputTuple>::type first_type;
+        typedef typename tuple_element<1, InputTuple>::type second_type;
+        typedef typename tuple_element<2, InputTuple>::type third_type;
+        typedef typename tuple_element<3, InputTuple>::type fourth_type;
+        typedef typename tuple_element<4, InputTuple>::type fifth_type;
+        typedef typename tuple_element<5, InputTuple>::type sixth_type;
+        typedef typename tuple_element<6, InputTuple>::type seventh_type;
+        typedef typename tuple_element<7, InputTuple>::type eighth_type;
+        typedef typename tuple_element<8, InputTuple>::type nineth_type;
+        typedef typename tuple_element<9, InputTuple>::type tenth_type;
+        typedef typename internal::tagged_msg<size_t, first_type, second_type, third_type,
+                                                      fourth_type, fifth_type, sixth_type,
+                                                      seventh_type, eighth_type, nineth_type,
+                                                      tenth_type> type;
+    };
+
+    // type generators
+    template<typename OutputTuple>
+    struct indexer_types : public input_types<tuple_size<OutputTuple>::value, OutputTuple> {
+        static const int N = tbb::flow::tuple_size<OutputTuple>::value;
+        typedef typename input_types<N, OutputTuple>::type output_type;
+        typedef typename wrap_tuple_elements<N,indexer_input_port,OutputTuple>::type input_ports_type;
+        typedef internal::indexer_node_FE<input_ports_type,output_type,OutputTuple> indexer_FE_type;
+        typedef internal::indexer_node_base<input_ports_type, output_type, OutputTuple> indexer_base_type;
+    };
+
+    template<class OutputTuple>
+    class unfolded_indexer_node : public indexer_types<OutputTuple>::indexer_base_type {
+    public:
+        typedef typename indexer_types<OutputTuple>::input_ports_type input_ports_type;
+        typedef OutputTuple tuple_types;
+        typedef typename indexer_types<OutputTuple>::output_type output_type;
+    private:
+        typedef typename indexer_types<OutputTuple>::indexer_base_type base_type;
+    public:
+        unfolded_indexer_node(graph& g) : base_type(g) {}
+        unfolded_indexer_node(const unfolded_indexer_node &other) : base_type(other) {}
+    };
+
+} /* namespace internal */
+
+#endif  /* __TBB__flow_graph_indexer_impl_H */
index 85c00694e76d15fea540fbf971a625647478d94f..11665acf90813373ddffc54dabb4788f387e226a 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__flow_graph_item_buffer_impl_H
 #error Do not #include this internal file directly; use public TBB headers instead.
 #endif
 
+#include "tbb/internal/_flow_graph_types_impl.h"  // for aligned_pair
+
+// in namespace tbb::flow::interface7 (included in _flow_graph_node_impl.h)
+
     //! Expandable buffer of items.  The possible operations are push, pop,
     //* tests for empty and so forth.  No mutual exclusion is built in.
+    //* objects are constructed into and explicitly-destroyed.  get_my_item gives
+    // a read-only reference to the item in the buffer.  set_my_item may be called
+    // with either an empty or occupied slot.
+
+    using internal::aligned_pair;
+    using internal::alignment_of;
+
+namespace internal {
+
     template <typename T, typename A=cache_aligned_allocator<T> >
     class item_buffer {
     public:
-        typedef T input_type;
-        typedef T output_type;
+        typedef T item_type;
+        enum buffer_item_state { no_item=0, has_item=1, reserved_item=2 };
     protected:
         typedef size_t size_type;
-        typedef std::pair< T, bool > item_type;
-        typedef typename A::template rebind<item_type>::other allocator_type;
+        typedef typename aligned_pair<item_type, buffer_item_state>::type buffer_item_type;
+        typedef typename A::template rebind<buffer_item_type>::other allocator_type;
 
-        item_type *my_array;
+        buffer_item_type *my_array;
         size_type my_array_size;
         static const size_type initial_buffer_size = 4;
         size_type my_head;
 
         bool buffer_empty() { return my_head == my_tail; }
 
-        item_type &item(size_type i) { return my_array[i & (my_array_size - 1) ]; } // may not be marked valid
+        buffer_item_type &item(size_type i) {
+            __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].second))%alignment_of<buffer_item_state>::value),NULL);
+            __TBB_ASSERT(!(size_type(&(my_array[i&(my_array_size-1)].first))%alignment_of<item_type>::value), NULL);
+            return my_array[i & (my_array_size - 1) ];
+        }
+
+        bool my_item_valid(size_type i) { return (i < my_tail) && (i >= my_head) && (item(i).second != no_item); }
+        bool my_item_reserved(size_type i) { return item(i).second == reserved_item; }
+
+        // object management in buffer
+        const item_type &get_my_item(size_t i) {
+            __TBB_ASSERT(my_item_valid(i),"attempt to get invalid item");
+            item_type *itm = (tbb::internal::punned_cast<item_type *>(&(item(i).first)));
+            return *(const item_type *)itm;
+        }
+
+        // may be called with an empty slot or a slot that has already been constructed into.
+        void set_my_item(size_t i, const item_type &o) { 
+            if(item(i).second != no_item) {
+                destroy_item(i);
+            }
+            new(&(item(i).first)) item_type(o);
+            item(i).second = has_item;
+        }
+
+        // destructively-fetch an object from the buffer
+        void fetch_item(size_t i, item_type &o) {
+            __TBB_ASSERT(my_item_valid(i), "Trying to fetch an empty slot");
+            o = get_my_item(i);  // could have std::move assign semantics
+            destroy_item(i);
+        }
 
-        bool item_valid(size_type i) { return item(i).second; }
+        // move an existing item from one slot to another.  The moved-to slot must be unoccupied,
+        // the moved-from slot must exist and not be reserved.  The after, from will be empty,
+        // to will be occupied but not reserved
+        void move_item(size_t to, size_t from) {
+            __TBB_ASSERT(!my_item_valid(to), "Trying to move to a non-empty slot");
+            __TBB_ASSERT(my_item_valid(from), "Trying to move from an empty slot");
+            set_my_item(to, get_my_item(from));   // could have std::move semantics
+            destroy_item(from);
 
-        void fetch_front(T &v) { __TBB_ASSERT(item_valid(my_head), "front not valid"); v = item(my_head).first; }
-        void fetch_back(T &v) { __TBB_ASSERT(item_valid(my_tail-1), "back not valid"); v = item(my_tail-1).first; }
+        }
 
-        void invalidate(size_type i) { __TBB_ASSERT(item_valid(i), "Item not valid"); item(i).second = false; }
-        void validate(size_type i) { __TBB_ASSERT(!item_valid(i), "Item already valid"); item(i).second = true; }
+        // put an item in an empty slot.  Return true if successful, else false
+        bool place_item(size_t here, const item_type &me) {
+#if !TBB_DEPRECATED_SEQUENCER_DUPLICATES
+            if(my_item_valid(here)) return false;
+#endif
+            set_my_item(here, me);
+            return true;
+        }
 
-        void invalidate_front() { invalidate(my_head); }
-        void validate_front() { validate(my_head); }
-        void invalidate_back() { invalidate(my_tail-1); }
+        // could be implemented with std::move semantics
+        void swap_items(size_t i, size_t j) {
+            __TBB_ASSERT(my_item_valid(i) && my_item_valid(j), "attempt to swap invalid item(s)");
+            item_type temp = get_my_item(i);
+            set_my_item(i, get_my_item(j));
+            set_my_item(j, temp);
+        }
 
-        size_type size() { return my_tail - my_head; }
+        void destroy_item(size_type i) {
+            __TBB_ASSERT(my_item_valid(i), "destruction of invalid item");
+            (tbb::internal::punned_cast<item_type *>(&(item(i).first)))->~item_type();
+            item(i).second = no_item;
+        }
+
+        // returns a copy of the front
+        void copy_front(item_type &v) {
+            __TBB_ASSERT(my_item_valid(my_head), "attempt to fetch head non-item");
+            v = get_my_item(my_head);
+        }
+        // returns a copy of the back
+        void copy_back(item_type &v) {
+            __TBB_ASSERT(my_item_valid(my_tail-1), "attempt to fetch head non-item");
+            v = get_my_item(my_tail-1);
+        }
+
+        // following methods are for reservation of the front of a bufffer. 
+        void reserve_item(size_type i) { __TBB_ASSERT(my_item_valid(i) && !my_item_reserved(i), "item cannot be reserved"); item(i).second = reserved_item; }
+        void release_item(size_type i) { __TBB_ASSERT(my_item_reserved(i), "item is not reserved"); item(i).second = has_item; }
+
+        void destroy_front() { destroy_item(my_head); ++my_head; }
+        void destroy_back() { destroy_item(my_tail-1); --my_tail; }
+
+        // we have to be able to test against a new tail value without changing my_tail
+        // grow_array doesn't work if we change my_tail when the old array is too small
+        size_type size(size_t new_tail = 0) { return (new_tail ? new_tail : my_tail) - my_head; }
         size_type capacity() { return my_array_size; }
-        bool buffer_full() { return size() == capacity(); }
+        // sequencer_node does not use this method, so we don't 
+        // need a version that passes in the new_tail value.
+        bool buffer_full() { return size() >= capacity(); }
 
         //! Grows the internal array.
         void grow_my_array( size_t minimum_size ) {
-            size_type old_size = my_array_size;
-            size_type new_size = old_size ? 2*old_size : initial_buffer_size;
+            // test that we haven't made the structure inconsistent.
+            __TBB_ASSERT(capacity() >= my_tail - my_head, "total items exceed capacity");
+            size_type new_size = my_array_size ? 2*my_array_size : initial_buffer_size;
             while( new_size<minimum_size )
                 new_size*=2;
 
-            item_type* new_array = allocator_type().allocate(new_size);
-            item_type* old_array = my_array;
+            buffer_item_type* new_array = allocator_type().allocate(new_size);
+
+            // initialize validity to "no"
+            for( size_type i=0; i<new_size; ++i ) { new_array[i].second = no_item; }
 
-            for( size_type i=0; i<new_size; ++i ) {
-                new (&(new_array[i].first)) input_type;
-                new_array[i].second = false;
+            for( size_type i=my_head; i<my_tail; ++i) {
+                if(my_item_valid(i)) {  // sequencer_node may have empty slots
+                    // placement-new copy-construct; could be std::move
+                    char *new_space = (char *)&(new_array[i&(new_size-1)].first);
+                    (void)new(new_space) item_type(get_my_item(i));
+                    new_array[i&(new_size-1)].second = item(i).second;
+                }
             }
 
-            size_t t=my_head;
-            for( size_type i=0; i<old_size; ++i, ++t )
-                new_array[t&(new_size-1)] = old_array[t&(old_size-1)];
+            clean_up_buffer(/*reset_pointers*/false);
+
             my_array = new_array;
             my_array_size = new_size;
-            if( old_array ) {
-                for( size_type i=0; i<old_size; ++i, ++t )
-                    old_array[i].first.~input_type();
-                allocator_type().deallocate(old_array,old_size);
-            }
         }
 
-        bool push_back(T &v) {
+        bool push_back(item_type &v) {
             if(buffer_full()) {
                 grow_my_array(size() + 1);
             }
-            item(my_tail) = std::make_pair( v, true );
+            set_my_item(my_tail, v);
             ++my_tail;
             return true;
         }
 
-        bool pop_back(T &v) {
-            if (!item_valid(my_tail-1)) {
+        bool pop_back(item_type &v) {
+            if (!my_item_valid(my_tail-1)) {
                 return false;
             }
-            fetch_back(v);
-            invalidate_back();
-            --my_tail;
+            copy_back(v);
+            destroy_back();
             return true;
         }
 
-        bool pop_front(T &v) {
-            if(!item_valid(my_head)) {
+        bool pop_front(item_type &v) {
+            if(!my_item_valid(my_head)) {
                 return false;
             }
-            fetch_front(v);
-            invalidate_front();
-            ++my_head;
+            copy_front(v);
+            destroy_front();
             return true;
         }
 
+        // This is used both for reset and for grow_my_array.  In the case of grow_my_array
+        // we want to retain the values of the head and tail.
+        void clean_up_buffer(bool reset_pointers) {
+            if (my_array) {
+                for( size_type i=my_head; i<my_tail; ++i ) {
+                    if(my_item_valid(i))
+                        destroy_item(i);
+                }
+                allocator_type().deallocate(my_array,my_array_size); 
+            }
+            my_array = NULL;
+            if(reset_pointers) {
+                my_head = my_tail = my_array_size = 0;
+            }
+        }
+
     public:
         //! Constructor
         item_buffer( ) : my_array(NULL), my_array_size(0),
         }
 
         ~item_buffer() {
-            if (my_array) {
-                for( size_type i=0; i<my_array_size; ++i ) {
-                    my_array[i].first.~input_type();
-                }
-                allocator_type().deallocate(my_array,my_array_size); 
-            }
+            clean_up_buffer(/*reset_pointers*/true);
         }
 
+        void reset() { clean_up_buffer(/*reset_pointers*/true); grow_my_array(initial_buffer_size); }
+
     };
 
     //! item_buffer with reservable front-end.  NOTE: if reserving, do not
     template<typename T, typename A=cache_aligned_allocator<T> >
     class reservable_item_buffer : public item_buffer<T, A> {
     protected:
-        using item_buffer<T, A>::buffer_empty;
-        using item_buffer<T, A>::fetch_front;
-        using item_buffer<T, A>::invalidate_front;
-        using item_buffer<T, A>::validate_front;
-        using item_buffer<T, A>::item_valid;
+        using item_buffer<T, A>::my_item_valid;
         using item_buffer<T, A>::my_head;
 
     public:
         reservable_item_buffer() : item_buffer<T, A>(), my_reserved(false) {}
+        void reset() {my_reserved = false; item_buffer<T,A>::reset(); }
     protected:
 
         bool reserve_front(T &v) {
-            if(my_reserved || !item_valid(my_head)) return false;
+            if(my_reserved || !my_item_valid(my_head)) return false;
             my_reserved = true;
             // reserving the head
-            fetch_front(v);
-            // invalidate the head, but don't commit until consume is called
-            invalidate_front();
+            this->copy_front(v);
+            this->reserve_item(this->my_head);
             return true;
         }
 
         void consume_front() {
             __TBB_ASSERT(my_reserved, "Attempt to consume a non-reserved item");
-            ++my_head;
+            this->destroy_front();
             my_reserved = false;
         }
 
         void release_front() {
             __TBB_ASSERT(my_reserved, "Attempt to release a non-reserved item");
-            validate_front();
+            this->release_item(this->my_head);
             my_reserved = false;
         }
 
         bool my_reserved;
     };
 
+}  // namespace internal
+
 #endif // __TBB__flow_graph_item_buffer_impl_H
index f24cfa4d5c3632df11a5d3a18a14436e84a2f295..3a8712134d2789501ec7b85902e25e7192406de4 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__flow_graph_join_impl_H
 #error Do not #include this internal file directly; use public TBB headers instead.
 #endif
 
+#include "_flow_graph_types_impl.h"
+
 namespace internal {
 
     typedef size_t tag_value;
     static const tag_value NO_TAG = tag_value(-1);
 
     struct forwarding_base {
-        forwarding_base(task *rt) : my_root_task(rt), current_tag(NO_TAG) {}
+        forwarding_base(graph &g) : my_graph_ptr(&g), current_tag(NO_TAG) {}
         virtual ~forwarding_base() {}
-        virtual void decrement_port_count() = 0;
+        // decrement_port_count may create a forwarding task.  If we cannot handle the task
+        // ourselves, ask decrement_port_count to deal with it.
+        virtual task * decrement_port_count(bool handle_task) = 0;
         virtual void increment_port_count() = 0;
-        virtual void increment_tag_count(tag_value /*t*/) {}
+        virtual task * increment_tag_count(tag_value /*t*/, bool /*handle_task*/) {return NULL;}
         // moved here so input ports can queue tasks
-        task* my_root_task;
+        graph* my_graph_ptr;
         tag_value current_tag; // so ports can refer to FE's desired items
     };
 
@@ -54,18 +50,18 @@ namespace internal {
 
         template< typename TupleType, typename PortType >
         static inline void set_join_node_pointer(TupleType &my_input, PortType *port) {
-            std::get<N-1>( my_input ).set_join_node_pointer(port);
+            tbb::flow::get<N-1>( my_input ).set_join_node_pointer(port);
             join_helper<N-1>::set_join_node_pointer( my_input, port );
         }
         template< typename TupleType >
         static inline void consume_reservations( TupleType &my_input ) {
-            std::get<N-1>( my_input ).consume();
+            tbb::flow::get<N-1>( my_input ).consume();
             join_helper<N-1>::consume_reservations( my_input );
         }
 
         template< typename TupleType >
         static inline void release_my_reservation( TupleType &my_input ) {
-            std::get<N-1>( my_input ).release();
+            tbb::flow::get<N-1>( my_input ).release();
         }
 
         template <typename TupleType>
@@ -76,7 +72,7 @@ namespace internal {
 
         template< typename InputTuple, typename OutputTuple >
         static inline bool reserve( InputTuple &my_input, OutputTuple &out) {
-            if ( !std::get<N-1>( my_input ).reserve( std::get<N-1>( out ) ) ) return false;
+            if ( !tbb::flow::get<N-1>( my_input ).reserve( tbb::flow::get<N-1>( out ) ) ) return false;
             if ( !join_helper<N-1>::reserve( my_input, out ) ) {
                 release_my_reservation( my_input );
                 return false;
@@ -86,7 +82,7 @@ namespace internal {
 
         template<typename InputTuple, typename OutputTuple>
         static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) {
-            bool res = std::get<N-1>(my_input).get_item(std::get<N-1>(out) ); // may fail
+            bool res = tbb::flow::get<N-1>(my_input).get_item(tbb::flow::get<N-1>(out) ); // may fail
             return join_helper<N-1>::get_my_item(my_input, out) && res;       // do get on other inputs before returning
         }
 
@@ -98,7 +94,7 @@ namespace internal {
         template<typename InputTuple>
         static inline void reset_my_port(InputTuple &my_input) {
             join_helper<N-1>::reset_my_port(my_input);
-            std::get<N-1>(my_input).reset_port();
+            tbb::flow::get<N-1>(my_input).reset_port();
         }
 
         template<typename InputTuple>
@@ -108,20 +104,26 @@ namespace internal {
 
         template<typename InputTuple, typename TagFuncTuple>
         static inline void set_tag_func(InputTuple &my_input, TagFuncTuple &my_tag_funcs) {
-            std::get<N-1>(my_input).set_my_original_tag_func(std::get<N-1>(my_tag_funcs));
-            std::get<N-1>(my_input).set_my_tag_func(std::get<N-1>(my_input).my_original_func()->clone());
-            std::get<N-1>(my_tag_funcs) = NULL;
+            tbb::flow::get<N-1>(my_input).set_my_original_tag_func(tbb::flow::get<N-1>(my_tag_funcs));
+            tbb::flow::get<N-1>(my_input).set_my_tag_func(tbb::flow::get<N-1>(my_input).my_original_func()->clone());
+            tbb::flow::get<N-1>(my_tag_funcs) = NULL;
             join_helper<N-1>::set_tag_func(my_input, my_tag_funcs);
         }
 
         template< typename TagFuncTuple1, typename TagFuncTuple2>
         static inline void copy_tag_functors(TagFuncTuple1 &my_inputs, TagFuncTuple2 &other_inputs) {
-            if(std::get<N-1>(other_inputs).my_original_func()) {
-                std::get<N-1>(my_inputs).set_my_tag_func(std::get<N-1>(other_inputs).my_original_func()->clone());
-                std::get<N-1>(my_inputs).set_my_original_tag_func(std::get<N-1>(other_inputs).my_original_func()->clone());
+            if(tbb::flow::get<N-1>(other_inputs).my_original_func()) {
+                tbb::flow::get<N-1>(my_inputs).set_my_tag_func(tbb::flow::get<N-1>(other_inputs).my_original_func()->clone());
+                tbb::flow::get<N-1>(my_inputs).set_my_original_tag_func(tbb::flow::get<N-1>(other_inputs).my_original_func()->clone());
             }
             join_helper<N-1>::copy_tag_functors(my_inputs, other_inputs);
         }
+
+        template<typename InputTuple>
+        static inline void reset_inputs(InputTuple &my_input __TBB_PFG_RESET_ARG(__TBB_COMMA reset_flags f)) {
+            join_helper<N-1>::reset_inputs(my_input __TBB_PFG_RESET_ARG(__TBB_COMMA f));
+            tbb::flow::get<N-1>(my_input).reset_receiver(__TBB_PFG_RESET_ARG(f));
+        }
     };
 
     template< >
@@ -129,17 +131,17 @@ namespace internal {
 
         template< typename TupleType, typename PortType >
         static inline void set_join_node_pointer(TupleType &my_input, PortType *port) {
-            std::get<0>( my_input ).set_join_node_pointer(port);
+            tbb::flow::get<0>( my_input ).set_join_node_pointer(port);
         }
 
         template< typename TupleType >
         static inline void consume_reservations( TupleType &my_input ) {
-            std::get<0>( my_input ).consume();
+            tbb::flow::get<0>( my_input ).consume();
         }
 
         template< typename TupleType >
         static inline void release_my_reservation( TupleType &my_input ) {
-            std::get<0>( my_input ).release();
+            tbb::flow::get<0>( my_input ).release();
         }
 
         template<typename TupleType>
@@ -149,12 +151,12 @@ namespace internal {
 
         template< typename InputTuple, typename OutputTuple >
         static inline bool reserve( InputTuple &my_input, OutputTuple &out) {
-            return std::get<0>( my_input ).reserve( std::get<0>( out ) );
+            return tbb::flow::get<0>( my_input ).reserve( tbb::flow::get<0>( out ) );
         }
 
         template<typename InputTuple, typename OutputTuple>
         static inline bool get_my_item( InputTuple &my_input, OutputTuple &out) {
-            return std::get<0>(my_input).get_item(std::get<0>(out));
+            return tbb::flow::get<0>(my_input).get_item(tbb::flow::get<0>(out));
         }
 
         template<typename InputTuple, typename OutputTuple>
@@ -164,7 +166,7 @@ namespace internal {
 
         template<typename InputTuple>
         static inline void reset_my_port(InputTuple &my_input) {
-            std::get<0>(my_input).reset_port();
+            tbb::flow::get<0>(my_input).reset_port();
         }
 
         template<typename InputTuple>
@@ -174,18 +176,22 @@ namespace internal {
 
         template<typename InputTuple, typename TagFuncTuple>
         static inline void set_tag_func(InputTuple &my_input, TagFuncTuple &my_tag_funcs) {
-            std::get<0>(my_input).set_my_original_tag_func(std::get<0>(my_tag_funcs));
-            std::get<0>(my_input).set_my_tag_func(std::get<0>(my_input).my_original_func()->clone());
-            std::get<0>(my_tag_funcs) = NULL;
+            tbb::flow::get<0>(my_input).set_my_original_tag_func(tbb::flow::get<0>(my_tag_funcs));
+            tbb::flow::get<0>(my_input).set_my_tag_func(tbb::flow::get<0>(my_input).my_original_func()->clone());
+            tbb::flow::get<0>(my_tag_funcs) = NULL;
         }
 
         template< typename TagFuncTuple1, typename TagFuncTuple2>
         static inline void copy_tag_functors(TagFuncTuple1 &my_inputs, TagFuncTuple2 &other_inputs) {
-            if(std::get<0>(other_inputs).my_original_func()) {
-                std::get<0>(my_inputs).set_my_tag_func(std::get<0>(other_inputs).my_original_func()->clone());
-                std::get<0>(my_inputs).set_my_original_tag_func(std::get<0>(other_inputs).my_original_func()->clone());
+            if(tbb::flow::get<0>(other_inputs).my_original_func()) {
+                tbb::flow::get<0>(my_inputs).set_my_tag_func(tbb::flow::get<0>(other_inputs).my_original_func()->clone());
+                tbb::flow::get<0>(my_inputs).set_my_original_tag_func(tbb::flow::get<0>(other_inputs).my_original_func()->clone());
             }
         }
+        template<typename InputTuple>
+        static inline void reset_inputs(InputTuple &my_input __TBB_PFG_RESET_ARG(__TBB_COMMA reset_flags f)) {
+            tbb::flow::get<0>(my_input).reset_receiver(__TBB_PFG_RESET_ARG(f));
+        }
     };
 
     //! The two-phase join port
@@ -194,9 +200,16 @@ namespace internal {
     public:
         typedef T input_type;
         typedef sender<T> predecessor_type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<predecessor_type *> predecessor_vector_type;
+#endif
     private:
         // ----------- Aggregator ------------
-        enum op_type { reg_pred, rem_pred, res_item, rel_res, con_res };
+        enum op_type { reg_pred, rem_pred, res_item, rel_res, con_res
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy
+#endif
+        };
         enum op_stat {WAIT=0, SUCCEEDED, FAILED};
         typedef reserving_port<T> my_class;
 
@@ -206,10 +219,14 @@ namespace internal {
             union {
                 T *my_arg;
                 predecessor_type *my_pred;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                size_t cnt_val;
+                predecessor_vector_type *pvec;
+#endif
             };
             reserving_port_operation(const T& e, op_type t) :
                 type(char(t)), my_arg(const_cast<T*>(&e)) {}
-            reserving_port_operation(const predecessor_type &s, op_type t) : type(char(t)), 
+            reserving_port_operation(const predecessor_type &s, op_type t) : type(char(t)),
                 my_pred(const_cast<predecessor_type *>(&s)) {}
             reserving_port_operation(op_type t) : type(char(t)) {}
         };
@@ -229,7 +246,7 @@ namespace internal {
                     no_predecessors = my_predecessors.empty();
                     my_predecessors.add(*(current->my_pred));
                     if ( no_predecessors ) {
-                        my_join->decrement_port_count( ); // may try to forward
+                        (void) my_join->decrement_port_count(true); // may try to forward
                     }
                     __TBB_store_with_release(current->status, SUCCEEDED);
                     break;
@@ -262,10 +279,36 @@ namespace internal {
                     my_predecessors.try_consume( );
                     __TBB_store_with_release(current->status, SUCCEEDED);
                     break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                case add_blt_pred:
+                    my_predecessors.internal_add_built_predecessor(*(current->my_pred));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case del_blt_pred:
+                    my_predecessors.internal_delete_built_predecessor(*(current->my_pred));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_pred_cnt:
+                    current->cnt_val = my_predecessors.predecessor_count();
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_pred_cpy:
+                    my_predecessors.copy_predecessors(*(current->pvec));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
                 }
             }
         }
 
+    protected:
+        template< typename R, typename B > friend class run_and_put_task;
+        template<typename X, typename Y> friend class internal::broadcast_cache;
+        template<typename X, typename Y> friend class internal::round_robin_cache;
+        task *try_put_task( const T & ) {
+            return NULL;
+        }
+
     public:
 
         //! Constructor
@@ -287,11 +330,6 @@ namespace internal {
             my_join = join;
         }
 
-        // always rejects, so arc is reversed (and reserves can be done.)
-        bool try_put( const T & ) {
-            return false;
-        }
-
         //! Add a predecessor
         bool register_predecessor( sender<T> &src ) {
             reserving_port_operation op_data(src, reg_pred);
@@ -325,6 +363,38 @@ namespace internal {
             my_aggregator.execute(&op_data);
         }
 
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/void internal_add_built_predecessor(predecessor_type &src) {
+            reserving_port_operation op_data(src, add_blt_pred);
+            my_aggregator.execute(&op_data);
+        }
+
+        /*override*/void internal_delete_built_predecessor(predecessor_type &src) {
+            reserving_port_operation op_data(src, del_blt_pred);
+            my_aggregator.execute(&op_data);
+        }
+
+        /*override*/size_t predecessor_count() {
+            reserving_port_operation op_data(blt_pred_cnt);
+            my_aggregator.execute(&op_data);
+            return op_data.cnt_val;
+        }
+
+        /*override*/void copy_predecessors(predecessor_vector_type &v) {
+            reserving_port_operation op_data(blt_pred_cpy);
+            op_data.pvec = &v;
+            my_aggregator.execute(&op_data);
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
+        /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            my_predecessors.reset(__TBB_PFG_RESET_ARG(f));
+            reserved = false;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            __TBB_ASSERT(!(f&rf_extract) || my_predecessors.empty(), "port edges not removed");
+#endif
+        }
+
     private:
         forwarding_base *my_join;
         reservable_predecessor_cache< T, null_mutex > my_predecessors;
@@ -338,10 +408,17 @@ namespace internal {
         typedef T input_type;
         typedef sender<T> predecessor_type;
         typedef queueing_port<T> my_node_type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<predecessor_type *> predecessor_vector_type;
+#endif
 
     // ----------- Aggregator ------------
     private:
-        enum op_type { try__put, get__item, res_port };
+        enum op_type { get__item, res_port, try__put_task
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            , add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy 
+#endif
+        };
         enum op_stat {WAIT=0, SUCCEEDED, FAILED};
         typedef queueing_port<T> my_class;
 
@@ -350,15 +427,26 @@ namespace internal {
             char type;
             T my_val;
             T *my_arg;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            sender<T> *pred;
+            size_t cnt_val;
+            predecessor_vector_type *pvec;
+#endif
+            task * bypass_t;
             // constructor for value parameter
             queueing_port_operation(const T& e, op_type t) :
-                // type(char(t)), my_val(const_cast<T>(e)) {}
-                type(char(t)), my_val(e) {}
+                type(char(t)), my_val(e)
+                , bypass_t(NULL)
+            {}
             // constructor for pointer parameter
             queueing_port_operation(const T* p, op_type t) :
-                type(char(t)), my_arg(const_cast<T*>(p)) {}
+                type(char(t)), my_arg(const_cast<T*>(p))
+                , bypass_t(NULL)
+            {}
             // constructor with no parameter
-            queueing_port_operation(op_type t) : type(char(t)) {}
+            queueing_port_operation(op_type t) : type(char(t))
+                , bypass_t(NULL)
+            {}
         };
 
         typedef internal::aggregating_functor<my_class, queueing_port_operation> my_handler;
@@ -372,15 +460,20 @@ namespace internal {
                 current = op_list;
                 op_list = op_list->next;
                 switch(current->type) {
-                case try__put:
-                    was_empty = this->buffer_empty();
-                    this->push_back(current->my_val);
-                    if (was_empty) my_join->decrement_port_count();
-                    __TBB_store_with_release(current->status, SUCCEEDED);
+                case try__put_task: {
+                        task *rtask = NULL;
+                        was_empty = this->buffer_empty();
+                        this->push_back(current->my_val);
+                        if (was_empty) rtask = my_join->decrement_port_count(false);
+                        else
+                            rtask = SUCCESSFULLY_ENQUEUED;
+                        current->bypass_t = rtask;
+                        __TBB_store_with_release(current->status, SUCCEEDED);
+                    }
                     break;
                 case get__item:
                     if(!this->buffer_empty()) {
-                        this->fetch_front(*(current->my_arg));
+                        this->copy_front(*(current->my_arg));
                         __TBB_store_with_release(current->status, SUCCEEDED);
                     }
                     else {
@@ -388,17 +481,48 @@ namespace internal {
                     }
                     break;
                 case res_port:
-                    __TBB_ASSERT(this->item_valid(this->my_head), "No item to reset");
-                    this->invalidate_front(); ++(this->my_head);
-                    if(this->item_valid(this->my_head)) {
-                        my_join->decrement_port_count();
+                    __TBB_ASSERT(this->my_item_valid(this->my_head), "No item to reset");
+                    this->destroy_front();
+                    if(this->my_item_valid(this->my_head)) {
+                        (void)my_join->decrement_port_count(true);
                     }
                     __TBB_store_with_release(current->status, SUCCEEDED);
                     break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                case add_blt_pred:
+                    my_built_predecessors.add_edge(*(current->pred));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case del_blt_pred:
+                    my_built_predecessors.delete_edge(*(current->pred));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_pred_cnt:
+                    current->cnt_val = my_built_predecessors.edge_count();
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_pred_cpy:
+                    my_built_predecessors.copy_edges(*(current->pvec));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
                 }
             }
         }
     // ------------ End Aggregator ---------------
+
+    protected:
+        template< typename R, typename B > friend class run_and_put_task;
+        template<typename X, typename Y> friend class internal::broadcast_cache;
+        template<typename X, typename Y> friend class internal::round_robin_cache;
+        /*override*/task *try_put_task(const T &v) {
+            queueing_port_operation op_data(v, try__put_task);
+            my_aggregator.execute(&op_data);
+            __TBB_ASSERT(op_data.status == SUCCEEDED || !op_data.bypass_t, "inconsistent return from aggregator");
+            if(!op_data.bypass_t) return SUCCESSFULLY_ENQUEUED;
+            return op_data.bypass_t;
+        }
+
     public:
 
         //! Constructor
@@ -418,13 +542,6 @@ namespace internal {
             my_join = join;
         }
 
-        /*override*/bool try_put(const T &v) {
-            queueing_port_operation op_data(v, try__put);
-            my_aggregator.execute(&op_data);
-            return op_data.status == SUCCEEDED;
-        }
-
-
         bool get_item( T &v ) {
             queueing_port_operation op_data(&v, get__item);
             my_aggregator.execute(&op_data);
@@ -439,8 +556,45 @@ namespace internal {
             return;
         }
 
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/void internal_add_built_predecessor(sender<T> &p) {
+            queueing_port_operation op_data(add_blt_pred);
+            op_data.pred = &p;
+            my_aggregator.execute(&op_data);
+        }
+
+        /*override*/void internal_delete_built_predecessor(sender<T> &p) {
+            queueing_port_operation op_data(del_blt_pred);
+            op_data.pred = &p;
+            my_aggregator.execute(&op_data);
+        }
+
+        /*override*/size_t predecessor_count() {
+            queueing_port_operation op_data(blt_pred_cnt);
+            my_aggregator.execute(&op_data);
+            return op_data.cnt_val;
+        }
+
+        /*override*/void copy_predecessors(predecessor_vector_type &v) {
+            queueing_port_operation op_data(blt_pred_cpy);
+            op_data.pvec = &v;
+            my_aggregator.execute(&op_data);
+        }
+
+        /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { 
+            item_buffer<T>::reset(); 
+            if (f & rf_extract)
+                my_built_predecessors.receiver_extract(*this);
+        }
+#else
+        /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { item_buffer<T>::reset(); }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
     private:
         forwarding_base *my_join;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        edge_container<sender<T> > my_built_predecessors;
+#endif
     };
 
 #include "_flow_graph_tagged_buffer_impl.h"
@@ -452,10 +606,16 @@ namespace internal {
         typedef sender<T> predecessor_type;
         typedef tag_matching_port<T> my_node_type;  // for forwarding, if needed
         typedef function_body<input_type, tag_value> my_tag_func_type;
+        typedef tagged_buffer<tag_value,T,NO_TAG> my_buffer_type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<predecessor_type *> predecessor_vector_type;
+#endif
     private:
 // ----------- Aggregator ------------
     private:
-        enum op_type { try__put, get__item, res_port };
+        enum op_type { try__put, get__item, res_port,
+            add_blt_pred, del_blt_pred, blt_pred_cnt, blt_pred_cpy
+        };
         enum op_stat {WAIT=0, SUCCEEDED, FAILED};
         typedef tag_matching_port<T> my_class;
 
@@ -464,10 +624,14 @@ namespace internal {
             char type;
             T my_val;
             T *my_arg;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            predecessor_type *pred;
+            size_t cnt_val;
+            predecessor_vector_type *pvec;
+#endif
             tag_value my_tag_value;
             // constructor for value parameter
             tag_matching_port_operation(const T& e, op_type t) :
-                // type(char(t)), my_val(const_cast<T>(e)) {}
                 type(char(t)), my_val(e) {}
             // constructor for pointer parameter
             tag_matching_port_operation(const T* p, op_type t) :
@@ -488,8 +652,8 @@ namespace internal {
                 switch(current->type) {
                 case try__put: {
                         bool was_inserted = this->tagged_insert(current->my_tag_value, current->my_val);
-                        if(!was_inserted) __TBB_ASSERT( false, "multiple insertions of same tag");
-                        __TBB_store_with_release(current->status, SUCCEEDED);
+                        // return failure if a duplicate insertion occurs
+                        __TBB_store_with_release(current->status, was_inserted ? SUCCEEDED : FAILED);
                     }
                     break;
                 case get__item:
@@ -504,10 +668,45 @@ namespace internal {
                     this->tagged_delete(my_join->current_tag);
                     __TBB_store_with_release(current->status, SUCCEEDED);
                     break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                case add_blt_pred:
+                    my_built_predecessors.add_edge(*(current->pred));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case del_blt_pred:
+                    my_built_predecessors.delete_edge(*(current->pred));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_pred_cnt:
+                    current->cnt_val = my_built_predecessors.edge_count();
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_pred_cpy:
+                    my_built_predecessors.copy_edges(*(current->pvec));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+#endif
                 }
             }
         }
 // ------------ End Aggregator ---------------
+    protected:
+        template< typename R, typename B > friend class run_and_put_task;
+        template<typename X, typename Y> friend class internal::broadcast_cache;
+        template<typename X, typename Y> friend class internal::round_robin_cache;
+        /*override*/task *try_put_task(const T& v) {
+            tag_matching_port_operation op_data(v, try__put);
+            op_data.my_tag_value = (*my_tag_func)(v);
+            task *rtask = NULL;
+            my_aggregator.execute(&op_data);
+            if(op_data.status == SUCCEEDED) {
+                rtask = my_join->increment_tag_count(op_data.my_tag_value, false);  // may spawn
+                // rtask has to reflect the return status of the try_put
+                if(!rtask) rtask = SUCCESSFULLY_ENQUEUED;
+            }
+            return rtask;
+        }
+
     public:
 
         tag_matching_port() : receiver<T>(), tagged_buffer<tag_value, T, NO_TAG>() {
@@ -543,30 +742,38 @@ namespace internal {
             my_tag_func = f;
         }
 
-        /*override*/bool try_put(const T& v) {
-            tag_matching_port_operation op_data(v, try__put);
-            op_data.my_tag_value = (*my_tag_func)(v);
+        bool get_item( T &v ) {
+            tag_matching_port_operation op_data(&v, get__item);
             my_aggregator.execute(&op_data);
-            if(op_data.status == SUCCEEDED) {
-                // the assertion in the aggregator above will ensure we do not call with the same
-                // tag twice.  We have to exit the aggregator to keep lock-ups from happening;
-                // the increment of the tag hash table in the FE is under a separate aggregator,
-                // so that is serialized.
-                // is a race possible?  I do not believe so; the increment may cause a build of
-                // an output tuple, but its component is already in the hash table for the port.
-                my_join->increment_tag_count(op_data.my_tag_value);  // may spawn
-
-            }
             return op_data.status == SUCCEEDED;
         }
 
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/void internal_add_built_predecessor(sender<T> &p) {
+            tag_matching_port_operation op_data(add_blt_pred);
+            op_data.pred = &p;
+            my_aggregator.execute(&op_data);
+        }
 
-        bool get_item( T &v ) {
-            tag_matching_port_operation op_data(&v, get__item);
+        /*override*/void internal_delete_built_predecessor(sender<T> &p) {
+            tag_matching_port_operation op_data(del_blt_pred);
+            op_data.pred = &p;
             my_aggregator.execute(&op_data);
-            return op_data.status == SUCCEEDED;
         }
 
+        /*override*/size_t predecessor_count() {
+            tag_matching_port_operation op_data(blt_pred_cnt);
+            my_aggregator.execute(&op_data);
+            return op_data.cnt_val;
+        }
+
+        /*override*/void copy_predecessors(predecessor_vector_type &v) {
+            tag_matching_port_operation op_data(blt_pred_cpy);
+            op_data.pvec = &v;
+            my_aggregator.execute(&op_data);
+        }
+#endif
+
         // reset_port is called when item is accepted by successor, but
         // is initiated by join_node.
         void reset_port() {
@@ -578,9 +785,22 @@ namespace internal {
         my_tag_func_type *my_func() { return my_tag_func; }
         my_tag_func_type *my_original_func() { return my_original_tag_func; }
 
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags f)) { 
+            my_buffer_type::reset(); 
+           if (f & rf_extract)
+              my_built_predecessors.receiver_extract(*this);
+        }
+#else
+        /*override*/void reset_receiver(__TBB_PFG_RESET_ARG(reset_flags /*f*/)) { my_buffer_type::reset(); }
+#endif
+
     private:
         // need map of tags to values
         forwarding_base *my_join;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        edge_container<predecessor_type> my_built_predecessors;
+#endif
         my_tag_func_type *my_tag_func;
         my_tag_func_type *my_original_tag_func;
     };  // tag_matching_port
@@ -597,17 +817,17 @@ namespace internal {
     template<typename InputTuple, typename OutputTuple>
     class join_node_FE<reserving, InputTuple, OutputTuple> : public forwarding_base {
     public:
-        static const int N = std::tuple_size<OutputTuple>::value;
+        static const int N = tbb::flow::tuple_size<OutputTuple>::value;
         typedef OutputTuple output_type;
         typedef InputTuple input_type;
         typedef join_node_base<reserving, InputTuple, OutputTuple> my_node_type; // for forwarding
 
-        join_node_FE(graph &g) : forwarding_base(g.root_task()), my_node(NULL) {
+        join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) {
             ports_with_no_inputs = N;
             join_helper<N>::set_join_node_pointer(my_inputs, this);
         }
 
-        join_node_FE(const join_node_FE& other) : forwarding_base(other.my_root_task), my_node(NULL) {
+        join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::my_graph_ptr)), my_node(NULL) {
             ports_with_no_inputs = N;
             join_helper<N>::set_join_node_pointer(my_inputs, this);
         }
@@ -619,15 +839,29 @@ namespace internal {
         }
 
         // if all input_ports have predecessors, spawn forward to try and consume tuples
-        void decrement_port_count() {
+        task * decrement_port_count(bool handle_task) {
             if(ports_with_no_inputs.fetch_and_decrement() == 1) {
-                task::enqueue( * new ( task::allocate_additional_child_of( *(this->my_root_task) ) )
-                    forward_task<my_node_type>(*my_node) );
+                task* tp = this->my_graph_ptr->root_task();
+                if(tp) {
+                    task *rtask = new ( task::allocate_additional_child_of( *tp ) )
+                        forward_task_bypass<my_node_type>(*my_node);
+                    if(!handle_task) return rtask;
+                    FLOW_SPAWN(*rtask);
+                }
             }
+            return NULL;
         }
 
-        input_type &inputs() { return my_inputs; }
+        input_type &input_ports() { return my_inputs; }
+
     protected:
+
+        void reset( __TBB_PFG_RESET_ARG( reset_flags f)) {
+            // called outside of parallel contexts
+            ports_with_no_inputs = N;
+            join_helper<N>::reset_inputs(my_inputs __TBB_PFG_RESET_ARG( __TBB_COMMA f));
+        }
+
         // all methods on input ports should be called under mutual exclusion from join_node_base.
 
         bool tuple_build_may_succeed() {
@@ -654,17 +888,17 @@ namespace internal {
     template<typename InputTuple, typename OutputTuple>
     class join_node_FE<queueing, InputTuple, OutputTuple> : public forwarding_base {
     public:
-        static const int N = std::tuple_size<OutputTuple>::value;
+        static const int N = tbb::flow::tuple_size<OutputTuple>::value;
         typedef OutputTuple output_type;
         typedef InputTuple input_type;
         typedef join_node_base<queueing, InputTuple, OutputTuple> my_node_type; // for forwarding
 
-        join_node_FE(graph &g) : forwarding_base(g.root_task()), my_node(NULL) {
+        join_node_FE(graph &g) : forwarding_base(g), my_node(NULL) {
             ports_with_no_items = N;
             join_helper<N>::set_join_node_pointer(my_inputs, this);
         }
 
-        join_node_FE(const join_node_FE& other) : forwarding_base(other.my_root_task), my_node(NULL) {
+        join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::my_graph_ptr)), my_node(NULL) {
             ports_with_no_items = N;
             join_helper<N>::set_join_node_pointer(my_inputs, this);
         }
@@ -677,17 +911,31 @@ namespace internal {
         }
 
         // if all input_ports have items, spawn forward to try and consume tuples
-        void decrement_port_count() {
+        task * decrement_port_count(bool handle_task)
+        {
             if(ports_with_no_items.fetch_and_decrement() == 1) {
-                task::enqueue( * new ( task::allocate_additional_child_of( *(this->my_root_task) ) )
-                    forward_task<my_node_type>(*my_node) );
+                task* tp = this->my_graph_ptr->root_task();
+                if(tp) {
+                    task *rtask = new ( task::allocate_additional_child_of( *tp ) )
+                        forward_task_bypass <my_node_type>(*my_node);
+                    if(!handle_task) return rtask;
+                    FLOW_SPAWN( *rtask);
+                }
             }
+            return NULL;
         }
 
         void increment_port_count() { __TBB_ASSERT(false, NULL); }  // should never be called
 
-        input_type &inputs() { return my_inputs; }
+        input_type &input_ports() { return my_inputs; }
+
     protected:
+
+        void reset( __TBB_PFG_RESET_ARG( reset_flags f)) {
+            reset_port_count();
+            join_helper<N>::reset_inputs(my_inputs __TBB_PFG_RESET_ARG( __TBB_COMMA f) );
+        }
+
         // all methods on input ports should be called under mutual exclusion from join_node_base.
 
         bool tuple_build_may_succeed() {
@@ -715,9 +963,10 @@ namespace internal {
     // tag_matching join input port.
     template<typename InputTuple, typename OutputTuple>
     class join_node_FE<tag_matching, InputTuple, OutputTuple> : public forwarding_base,
+             //     buffer of tag value counts                       buffer of output items
              public tagged_buffer<tag_value, size_t, NO_TAG>, public item_buffer<OutputTuple> {
     public:
-        static const int N = std::tuple_size<OutputTuple>::value;
+        static const int N = tbb::flow::tuple_size<OutputTuple>::value;
         typedef OutputTuple output_type;
         typedef InputTuple input_type;
         typedef tagged_buffer<tag_value, size_t, NO_TAG> my_tag_buffer;
@@ -739,14 +988,15 @@ namespace internal {
                 tag_value my_val;
                 output_type* my_output;
             };
+            task *bypass_t;
+            bool enqueue_task;
             // constructor for value parameter
-            tag_matching_FE_operation(const tag_value& e, op_type t) :
-                // type(char(t)), my_val(const_cast<T>(e)) {}
-                type(char(t)), my_val(e) {}
-            tag_matching_FE_operation(output_type *p, op_type t) :
-                type(char(t)), my_output(p) {}
+            tag_matching_FE_operation(const tag_value& e , bool q_task , op_type t) : type(char(t)), my_val(e),
+                 bypass_t(NULL), enqueue_task(q_task) {}
+            tag_matching_FE_operation(output_type *p, op_type t) : type(char(t)), my_output(p), bypass_t(NULL),
+                 enqueue_task(true) {}
             // constructor with no parameter
-            tag_matching_FE_operation(op_type t) : type(char(t)) {}
+            tag_matching_FE_operation(op_type t) : type(char(t)), bypass_t(NULL), enqueue_task(true) {}
         };
 
         typedef internal::aggregating_functor<my_class, tag_matching_FE_operation> my_handler;
@@ -754,26 +1004,35 @@ namespace internal {
         aggregator<my_handler, tag_matching_FE_operation> my_aggregator;
 
         // called from aggregator, so serialized
-        void fill_output_buffer(bool should_enqueue) {
+        // construct as many output objects as possible.
+        // returns a task pointer if the a task would have been enqueued but we asked that
+        // it be returned.  Otherwise returns NULL.
+        task * fill_output_buffer(tag_value t, bool should_enqueue, bool handle_task) {
             output_type l_out;
-            bool do_fwd = should_enqueue && this->buffer_empty();
-            while(find_value_tag(this->current_tag,N)) {
-                this->tagged_delete(this->current_tag);
-                if(join_helper<N>::get_items(my_inputs, l_out)) {  //  <== call back
-                    this->push_back(l_out);
-                    if(do_fwd) {
-                        task::enqueue( * new ( task::allocate_additional_child_of( *(this->my_root_task) ) )
-                        forward_task<my_node_type>(*my_node) );
-                        do_fwd = false;
+            task *rtask = NULL;
+            task* tp = this->my_graph_ptr->root_task();
+            bool do_fwd = should_enqueue && this->buffer_empty() && tp;
+            this->current_tag = t;
+            this->tagged_delete(this->current_tag);   // remove the tag
+            if(join_helper<N>::get_items(my_inputs, l_out)) {  //  <== call back
+                this->push_back(l_out);
+                if(do_fwd) {  // we enqueue if receiving an item from predecessor, not if successor asks for item
+                    rtask = new ( task::allocate_additional_child_of( *tp ) )
+                        forward_task_bypass<my_node_type>(*my_node);
+                    if(handle_task) {
+                        FLOW_SPAWN(*rtask);
+                        rtask = NULL;
                     }
-                    // retire the input values
-                    join_helper<N>::reset_ports(my_inputs);  //  <== call back
-                    this->current_tag = NO_TAG;    
-                }
-                else {
-                    __TBB_ASSERT(false, "should have had something to push");
+                    do_fwd = false;
                 }
+                // retire the input values
+                join_helper<N>::reset_ports(my_inputs);  //  <== call back
+                this->current_tag = NO_TAG;
             }
+            else {
+                __TBB_ASSERT(false, "should have had something to push");
+            }
+            return rtask;
         }
 
         void handle_operations(tag_matching_FE_operation* op_list) {
@@ -784,31 +1043,29 @@ namespace internal {
                 switch(current->type) {
                 case res_count:  // called from BE
                     {
-                        output_type l_out;
-                        this->pop_front(l_out);  // don't care about returned value.
-                        // buffer as many tuples as we can make
-                        fill_output_buffer(true);
+                        this->destroy_front();
                         __TBB_store_with_release(current->status, SUCCEEDED);
                     }
                     break;
                 case inc_count: {  // called from input ports
                         size_t *p = 0;
                         tag_value t = current->my_val;
+                        bool do_enqueue = current->enqueue_task;
                         if(!(this->tagged_find_ref(t,p))) {
                             this->tagged_insert(t, 0);
                             if(!(this->tagged_find_ref(t,p))) {
-                                __TBB_ASSERT(false, NULL);
+                                __TBB_ASSERT(false, "should find tag after inserting it");
                             }
                         }
                         if(++(*p) == size_t(N)) {
-                            task::enqueue( * new ( task::allocate_additional_child_of( *(this->my_root_task) ) )
-                            forward_task<my_node_type>(*my_node) );
+                            task *rtask = fill_output_buffer(t, true, do_enqueue);
+                            __TBB_ASSERT(!rtask || !do_enqueue, "task should not be returned");
+                            current->bypass_t = rtask;
                         }
                     }
                     __TBB_store_with_release(current->status, SUCCEEDED);
                     break;
                 case may_succeed:  // called from BE
-                    fill_output_buffer(false);
                     __TBB_store_with_release(current->status, this->buffer_empty() ? FAILED : SUCCEEDED);
                     break;
                 case try_make:  // called from BE
@@ -816,7 +1073,7 @@ namespace internal {
                         __TBB_store_with_release(current->status, FAILED);
                     }
                     else {
-                        this->fetch_front(*(current->my_output));
+                        this->copy_front(*(current->my_output));
                         __TBB_store_with_release(current->status, SUCCEEDED);
                     }
                     break;
@@ -827,13 +1084,13 @@ namespace internal {
 
     public:
         template<typename FunctionTuple>
-        join_node_FE(graph &g, FunctionTuple tag_funcs) : forwarding_base(g.root_task()), my_node(NULL) {
+        join_node_FE(graph &g, FunctionTuple tag_funcs) : forwarding_base(g), my_node(NULL) {
             join_helper<N>::set_join_node_pointer(my_inputs, this);
             join_helper<N>::set_tag_func(my_inputs, tag_funcs);
             my_aggregator.initialize_handler(my_handler(this));
         }
 
-        join_node_FE(const join_node_FE& other) : forwarding_base(other.my_root_task), my_tag_buffer(),
+        join_node_FE(const join_node_FE& other) : forwarding_base(*(other.forwarding_base::my_graph_ptr)), my_tag_buffer(),
         output_buffer_type() {
             my_node = NULL;
             join_helper<N>::set_join_node_pointer(my_inputs, this);
@@ -851,18 +1108,30 @@ namespace internal {
         }
 
         // if all input_ports have items, spawn forward to try and consume tuples
-        void increment_tag_count(tag_value t) {  // called from input_ports
-            tag_matching_FE_operation op_data(t, inc_count);
+        // return a task if we are asked and did create one.
+        task *increment_tag_count(tag_value t, bool handle_task) {  // called from input_ports
+            tag_matching_FE_operation op_data(t, handle_task, inc_count);
             my_aggregator.execute(&op_data);
-            return;
+            return op_data.bypass_t;
         }
 
-        void decrement_port_count() { __TBB_ASSERT(false, NULL); }
+        /*override*/ task *decrement_port_count(bool /*handle_task*/) { __TBB_ASSERT(false, NULL); return NULL; }
 
         void increment_port_count() { __TBB_ASSERT(false, NULL); }  // should never be called
 
-        input_type &inputs() { return my_inputs; }
+        input_type &input_ports() { return my_inputs; }
+
     protected:
+
+        void reset( __TBB_PFG_RESET_ARG( reset_flags f )) {
+            // called outside of parallel contexts
+            join_helper<N>::reset_inputs(my_inputs __TBB_PFG_RESET_ARG( __TBB_COMMA f));
+
+            my_tag_buffer::reset();  // have to reset the tag counts
+            output_buffer_type::reset();  // also the queue of outputs
+            my_node->current_tag = NO_TAG;
+        }
+
         // all methods on input ports should be called under mutual exclusion from join_node_base.
 
         bool tuple_build_may_succeed() {  // called from back-end
@@ -895,6 +1164,8 @@ namespace internal {
     template<graph_buffer_policy JP, typename InputTuple, typename OutputTuple>
     class join_node_base : public graph_node, public join_node_FE<JP, InputTuple, OutputTuple>,
                            public sender<OutputTuple> {
+    protected:
+        using graph_node::my_graph;
     public:
         typedef OutputTuple output_type;
 
@@ -904,10 +1175,17 @@ namespace internal {
         using input_ports_type::try_to_make_tuple;
         using input_ports_type::tuple_accepted;
         using input_ports_type::tuple_rejected;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<successor_type *> successor_vector_type;
+#endif
 
     private:
         // ----------- Aggregator ------------
-        enum op_type { reg_succ, rem_succ, try__get, do_fwrd };
+        enum op_type { reg_succ, rem_succ, try__get, do_fwrd, do_fwrd_bypass
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            , add_blt_succ, del_blt_succ, blt_succ_cnt, blt_succ_cpy
+#endif
+        };
         enum op_stat {WAIT=0, SUCCEEDED, FAILED};
         typedef join_node_base<JP,InputTuple,OutputTuple> my_class;
 
@@ -917,12 +1195,17 @@ namespace internal {
             union {
                 output_type *my_arg;
                 successor_type *my_succ;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                size_t cnt_val;
+                successor_vector_type *svec;
+#endif
             };
-            join_node_base_operation(const output_type& e, op_type t) :
-                type(char(t)), my_arg(const_cast<output_type*>(&e)) {}
-            join_node_base_operation(const successor_type &s, op_type t) : type(char(t)), 
-                my_succ(const_cast<successor_type *>(&s)) {}
-            join_node_base_operation(op_type t) : type(char(t)) {}
+            task *bypass_t;
+            join_node_base_operation(const output_type& e, op_type t) : type(char(t)),
+                my_arg(const_cast<output_type*>(&e)), bypass_t(NULL) {}
+            join_node_base_operation(const successor_type &s, op_type t) : type(char(t)),
+                my_succ(const_cast<successor_type *>(&s)), bypass_t(NULL) {}
+            join_node_base_operation(op_type t) : type(char(t)), bypass_t(NULL) {}
         };
 
         typedef internal::aggregating_functor<my_class, join_node_base_operation> my_handler;
@@ -936,14 +1219,18 @@ namespace internal {
                 current = op_list;
                 op_list = op_list->next;
                 switch(current->type) {
-                case reg_succ:
-                    my_successors.register_successor(*(current->my_succ));
-                    if(tuple_build_may_succeed() && !forwarder_busy) {
-                        task::enqueue( * new ( task::allocate_additional_child_of(*(this->my_root_task)) )
-                                forward_task<join_node_base<JP,InputTuple,OutputTuple> >(*this));
-                        forwarder_busy = true;
+                case reg_succ: {
+                        my_successors.register_successor(*(current->my_succ));
+                        task* tp = this->graph_node::my_graph.root_task();
+                        if(tuple_build_may_succeed() && !forwarder_busy && tp) {
+                            task *rtask = new ( task::allocate_additional_child_of(*tp) )
+                                    forward_task_bypass
+                                    <join_node_base<JP,InputTuple,OutputTuple> >(*this);
+                            FLOW_SPAWN(*rtask);
+                            forwarder_busy = true;
+                        }
+                        __TBB_store_with_release(current->status, SUCCEEDED);
                     }
-                    __TBB_store_with_release(current->status, SUCCEEDED);
                     break;
                 case rem_succ:
                     my_successors.remove_successor(*(current->my_succ));
@@ -959,14 +1246,17 @@ namespace internal {
                     }
                     else __TBB_store_with_release(current->status, FAILED);
                     break;
-                case do_fwrd: {
+                case do_fwrd_bypass: {
                         bool build_succeeded;
+                        task *last_task = NULL;
                         output_type out;
                         if(tuple_build_may_succeed()) {
                             do {
                                 build_succeeded = try_to_make_tuple(out);
                                 if(build_succeeded) {
-                                    if(my_successors.try_put(out)) {
+                                    task *new_task = my_successors.try_put_task(out);
+                                    last_task = combine_tasks(last_task, new_task);
+                                    if(new_task) {
                                         tuple_accepted();
                                     }
                                     else {
@@ -976,23 +1266,42 @@ namespace internal {
                                 }
                             } while(build_succeeded);
                         }
+                        current->bypass_t = last_task;
                         __TBB_store_with_release(current->status, SUCCEEDED);
                         forwarder_busy = false;
                     }
                     break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                case add_blt_succ:
+                    my_successors.internal_add_built_successor(*(current->my_succ));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case del_blt_succ:
+                    my_successors.internal_delete_built_successor(*(current->my_succ));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_succ_cnt:
+                    current->cnt_val = my_successors.successor_count();
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+                case blt_succ_cpy:
+                    my_successors.copy_successors(*(current->svec));
+                    __TBB_store_with_release(current->status, SUCCEEDED);
+                    break;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
                 }
             }
         }
         // ---------- end aggregator -----------
     public:
-        join_node_base(graph &g) : input_ports_type(g), forwarder_busy(false) {
+        join_node_base(graph &g) : graph_node(g), input_ports_type(g), forwarder_busy(false) {
             my_successors.set_owner(this);
             input_ports_type::set_my_node(this);
             my_aggregator.initialize_handler(my_handler(this));
         }
 
         join_node_base(const join_node_base& other) :
-            graph_node(), input_ports_type(other),
+            graph_node(other.graph_node::my_graph), input_ports_type(other),
             sender<OutputTuple>(), forwarder_busy(false), my_successors() {
             my_successors.set_owner(this);
             input_ports_type::set_my_node(this);
@@ -1000,7 +1309,7 @@ namespace internal {
         }
 
         template<typename FunctionTuple>
-        join_node_base(graph &g, FunctionTuple f) : input_ports_type(g, f), forwarder_busy(false) {
+        join_node_base(graph &g, FunctionTuple f) : graph_node(g), input_ports_type(g, f), forwarder_busy(false) {
             my_successors.set_owner(this);
             input_ports_type::set_my_node(this);
             my_aggregator.initialize_handler(my_handler(this));
@@ -1024,263 +1333,68 @@ namespace internal {
             return op_data.status == SUCCEEDED;
         }
 
-    private:
-        broadcast_cache<output_type, null_rw_mutex> my_successors;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/void internal_add_built_successor( successor_type &r) {
+            join_node_base_operation op_data(r, add_blt_succ);
+            my_aggregator.execute(&op_data);
+        }
 
-        friend class forward_task< join_node_base<JP, InputTuple, OutputTuple> >;
+        /*override*/void internal_delete_built_successor( successor_type &r) {
+            join_node_base_operation op_data(r, del_blt_succ);
+            my_aggregator.execute(&op_data);
+        }
 
-        void forward() {
-            join_node_base_operation op_data(do_fwrd);
+        /*override*/size_t successor_count() {
+            join_node_base_operation op_data(blt_succ_cnt);
             my_aggregator.execute(&op_data);
+            return op_data.cnt_val;
         }
-    };
 
-    //! unfolded_join_node : passes input_ports_tuple_type to join_node_base.  We build the input port type
-    //  using tuple_element.  The class PT is the port type (reserving_port, queueing_port, tag_matching_port)
-    //  and should match the graph_buffer_policy.
-    template<int N, template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node;
-
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<2,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type> >,
-        OutputTuple
-                  >
-                  {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
-    };
+        /*override*/ void copy_successors(successor_vector_type &v) {
+            join_node_base_operation op_data(blt_succ_cpy);
+            op_data.svec = &v;
+            my_aggregator.execute(&op_data);
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<3,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type> >,
-        OutputTuple
-                    >
-                    {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
-    };
+    protected:
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<4,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type> >,
-        OutputTuple
-                    > {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
-    };
+        /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) {
+            input_ports_type::reset(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            my_successors.reset(f);
+#endif
+        }
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<5,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type>,
-                PT<typename std::tuple_element<4,OutputTuple>::type> >,
-        OutputTuple
-                > {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type>, 
-                PT<typename std::tuple_element<4,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
     private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
-    };
+        broadcast_cache<output_type, null_rw_mutex> my_successors;
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<6,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type>,
-                PT<typename std::tuple_element<4,OutputTuple>::type>,
-                PT<typename std::tuple_element<5,OutputTuple>::type> >,
-        OutputTuple
-                    > {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type>, 
-                PT<typename std::tuple_element<4,OutputTuple>::type>, 
-                PT<typename std::tuple_element<5,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
-    };
+        friend class forward_task_bypass< join_node_base<JP, InputTuple, OutputTuple> >;
+        task *forward_task() {
+            join_node_base_operation op_data(do_fwrd_bypass);
+            my_aggregator.execute(&op_data);
+            return op_data.bypass_t;
+        }
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<7,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type>,
-                PT<typename std::tuple_element<4,OutputTuple>::type>,
-                PT<typename std::tuple_element<5,OutputTuple>::type>,
-                PT<typename std::tuple_element<6,OutputTuple>::type> >,
-        OutputTuple
-                > {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type>, 
-                PT<typename std::tuple_element<4,OutputTuple>::type>, 
-                PT<typename std::tuple_element<5,OutputTuple>::type>, 
-                PT<typename std::tuple_element<6,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<8,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type>,
-                PT<typename std::tuple_element<4,OutputTuple>::type>,
-                PT<typename std::tuple_element<5,OutputTuple>::type>,
-                PT<typename std::tuple_element<6,OutputTuple>::type>,
-                PT<typename std::tuple_element<7,OutputTuple>::type> >,
-        OutputTuple
-                > {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type>, 
-                PT<typename std::tuple_element<4,OutputTuple>::type>, 
-                PT<typename std::tuple_element<5,OutputTuple>::type>, 
-                PT<typename std::tuple_element<6,OutputTuple>::type>, 
-                PT<typename std::tuple_element<7,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
+    // join base class type generator
+    template<int N, template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
+    struct join_base {
+        typedef typename internal::join_node_base<JP, typename wrap_tuple_elements<N,PT,OutputTuple>::type, OutputTuple> type;
     };
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<9,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type>,
-                PT<typename std::tuple_element<4,OutputTuple>::type>,
-                PT<typename std::tuple_element<5,OutputTuple>::type>,
-                PT<typename std::tuple_element<6,OutputTuple>::type>,
-                PT<typename std::tuple_element<7,OutputTuple>::type>,
-                PT<typename std::tuple_element<8,OutputTuple>::type> >,
-        OutputTuple
-                > {
-    public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type>, 
-                PT<typename std::tuple_element<4,OutputTuple>::type>, 
-                PT<typename std::tuple_element<5,OutputTuple>::type>, 
-                PT<typename std::tuple_element<6,OutputTuple>::type>, 
-                PT<typename std::tuple_element<7,OutputTuple>::type>, 
-                PT<typename std::tuple_element<8,OutputTuple>::type> > input_ports_tuple_type;
-        typedef OutputTuple output_type;
-    private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
-    public:
-        unfolded_join_node(graph &g) : base_type(g) {}
-        unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
-    };
+    //! unfolded_join_node : passes input_ports_type to join_node_base.  We build the input port type
+    //  using tuple_element.  The class PT is the port type (reserving_port, queueing_port, tag_matching_port)
+    //  and should match the graph_buffer_policy.
 
-    template<template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
-    class unfolded_join_node<10,PT,OutputTuple,JP> : public internal::join_node_base<JP,
-        std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>,
-                PT<typename std::tuple_element<1,OutputTuple>::type>,
-                PT<typename std::tuple_element<2,OutputTuple>::type>,
-                PT<typename std::tuple_element<3,OutputTuple>::type>,
-                PT<typename std::tuple_element<4,OutputTuple>::type>,
-                PT<typename std::tuple_element<5,OutputTuple>::type>,
-                PT<typename std::tuple_element<6,OutputTuple>::type>,
-                PT<typename std::tuple_element<7,OutputTuple>::type>,
-                PT<typename std::tuple_element<8,OutputTuple>::type>,
-                PT<typename std::tuple_element<9,OutputTuple>::type> >,
-        OutputTuple
-                > {
+    template<int N, template<class> class PT, typename OutputTuple, graph_buffer_policy JP>
+    class unfolded_join_node : public join_base<N,PT,OutputTuple,JP>::type {
     public:
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,OutputTuple>::type>, 
-                PT<typename std::tuple_element<1,OutputTuple>::type>, 
-                PT<typename std::tuple_element<2,OutputTuple>::type>, 
-                PT<typename std::tuple_element<3,OutputTuple>::type>, 
-                PT<typename std::tuple_element<4,OutputTuple>::type>, 
-                PT<typename std::tuple_element<5,OutputTuple>::type>, 
-                PT<typename std::tuple_element<6,OutputTuple>::type>, 
-                PT<typename std::tuple_element<7,OutputTuple>::type>, 
-                PT<typename std::tuple_element<8,OutputTuple>::type>, 
-                PT<typename std::tuple_element<9,OutputTuple>::type> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<N, PT, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<JP, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<JP, input_ports_type, output_type > base_type;
     public:
         unfolded_join_node(graph &g) : base_type(g) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
@@ -1290,212 +1404,168 @@ namespace internal {
     // differ.
 
     template<typename OutputTuple>
-    class unfolded_join_node<2,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type> >,
-        OutputTuple
-                  >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
+    class unfolded_join_node<2,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<2,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<2,tag_matching_port,OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
-        typedef typename std::tuple< f0_p, f1_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p > func_initializer_type;
     public:
-        template<typename B0, typename B1>
-        unfolded_join_node(graph &g, B0 b0, B1 b1) : base_type(g,
+        template<typename Body0, typename Body1>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1) : base_type(g,
                 func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1)
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
 
     template<typename OutputTuple>
-    class unfolded_join_node<3,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type> >,
-        OutputTuple
-                  >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
+    class unfolded_join_node<3,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<3,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>
-            > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<3, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2) : base_type(g,
+        template<typename Body0, typename Body1, typename Body2>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2) : base_type(g,
                 func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2)
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
 
     template<typename OutputTuple>
-    class unfolded_join_node<4,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
+    class unfolded_join_node<4,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<4,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<4, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
         typedef typename internal::function_body<T3, tag_value> *f3_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3) : base_type(g,
+        template<typename Body0, typename Body1, typename Body2, typename Body3>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3) : base_type(g,
                 func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3)
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
 
     template<typename OutputTuple>
-    class unfolded_join_node<5,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<4,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
-        typedef typename std::tuple_element<4, OutputTuple>::type T4;
+    class unfolded_join_node<5,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<5,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
+        typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3>, tag_matching_port<T4> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<5, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
         typedef typename internal::function_body<T3, tag_value> *f3_p;
         typedef typename internal::function_body<T4, tag_value> *f4_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3, typename B4>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4) : base_type(g,
+        template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4) : base_type(g,
                 func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3),
-                    new internal::function_body_leaf<T4, tag_value, B4>(b4)
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3),
+                    new internal::function_body_leaf<T4, tag_value, Body4>(body4)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
 
+#if __TBB_VARIADIC_MAX >= 6
     template<typename OutputTuple>
-    class unfolded_join_node<6,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<4,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<5,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
-        typedef typename std::tuple_element<4, OutputTuple>::type T4;
-        typedef typename std::tuple_element<5, OutputTuple>::type T5;
+    class unfolded_join_node<6,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<6,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
+        typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4;
+        typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3>, tag_matching_port<T4>, tag_matching_port<T5> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<6, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
         typedef typename internal::function_body<T3, tag_value> *f3_p;
         typedef typename internal::function_body<T4, tag_value> *f4_p;
         typedef typename internal::function_body<T5, tag_value> *f5_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5) : base_type(g,
-                func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3),
-                    new internal::function_body_leaf<T4, tag_value, B4>(b4),
-                    new internal::function_body_leaf<T5, tag_value, B5>(b5)
+        template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4, typename Body5>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4, Body5 body5)
+                : base_type(g, func_initializer_type(
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3),
+                    new internal::function_body_leaf<T4, tag_value, Body4>(body4),
+                    new internal::function_body_leaf<T5, tag_value, Body5>(body5)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 7
     template<typename OutputTuple>
-    class unfolded_join_node<7,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<4,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<5,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<6,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
-        typedef typename std::tuple_element<4, OutputTuple>::type T4;
-        typedef typename std::tuple_element<5, OutputTuple>::type T5;
-        typedef typename std::tuple_element<6, OutputTuple>::type T6;
+    class unfolded_join_node<7,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<7,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
+        typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4;
+        typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5;
+        typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3>, tag_matching_port<T4>, tag_matching_port<T5>, tag_matching_port<T6>
-            > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<7, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
@@ -1503,50 +1573,41 @@ namespace internal {
         typedef typename internal::function_body<T4, tag_value> *f4_p;
         typedef typename internal::function_body<T5, tag_value> *f5_p;
         typedef typename internal::function_body<T6, tag_value> *f6_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6) : base_type(g,
-                func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3),
-                    new internal::function_body_leaf<T4, tag_value, B4>(b4),
-                    new internal::function_body_leaf<T5, tag_value, B5>(b5),
-                    new internal::function_body_leaf<T6, tag_value, B6>(b6)
+        template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
+                 typename Body5, typename Body6>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
+                Body5 body5, Body6 body6) : base_type(g, func_initializer_type(
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3),
+                    new internal::function_body_leaf<T4, tag_value, Body4>(body4),
+                    new internal::function_body_leaf<T5, tag_value, Body5>(body5),
+                    new internal::function_body_leaf<T6, tag_value, Body6>(body6)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 8
     template<typename OutputTuple>
-    class unfolded_join_node<8,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<4,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<5,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<6,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<7,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
-        typedef typename std::tuple_element<4, OutputTuple>::type T4;
-        typedef typename std::tuple_element<5, OutputTuple>::type T5;
-        typedef typename std::tuple_element<6, OutputTuple>::type T6;
-        typedef typename std::tuple_element<7, OutputTuple>::type T7;
+    class unfolded_join_node<8,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<8,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
+        typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4;
+        typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5;
+        typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6;
+        typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3>, tag_matching_port<T4>, tag_matching_port<T5>, tag_matching_port<T6>,
-                tag_matching_port<T7> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<8, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
@@ -1555,53 +1616,43 @@ namespace internal {
         typedef typename internal::function_body<T5, tag_value> *f5_p;
         typedef typename internal::function_body<T6, tag_value> *f6_p;
         typedef typename internal::function_body<T7, tag_value> *f7_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7) : base_type(g,
-                func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3),
-                    new internal::function_body_leaf<T4, tag_value, B4>(b4),
-                    new internal::function_body_leaf<T5, tag_value, B5>(b5),
-                    new internal::function_body_leaf<T6, tag_value, B6>(b6),
-                    new internal::function_body_leaf<T7, tag_value, B7>(b7)
+        template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
+                 typename Body5, typename Body6, typename Body7>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
+                Body5 body5, Body6 body6, Body7 body7) : base_type(g, func_initializer_type(
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3),
+                    new internal::function_body_leaf<T4, tag_value, Body4>(body4),
+                    new internal::function_body_leaf<T5, tag_value, Body5>(body5),
+                    new internal::function_body_leaf<T6, tag_value, Body6>(body6),
+                    new internal::function_body_leaf<T7, tag_value, Body7>(body7)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 9
     template<typename OutputTuple>
-    class unfolded_join_node<9,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<4,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<5,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<6,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<7,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<8,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
-        typedef typename std::tuple_element<4, OutputTuple>::type T4;
-        typedef typename std::tuple_element<5, OutputTuple>::type T5;
-        typedef typename std::tuple_element<6, OutputTuple>::type T6;
-        typedef typename std::tuple_element<7, OutputTuple>::type T7;
-        typedef typename std::tuple_element<8, OutputTuple>::type T8;
+    class unfolded_join_node<9,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<9,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
+        typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4;
+        typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5;
+        typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6;
+        typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7;
+        typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3>, tag_matching_port<T4>, tag_matching_port<T5>, tag_matching_port<T6>,
-                tag_matching_port<T7>, tag_matching_port<T8> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<9, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
@@ -1611,56 +1662,45 @@ namespace internal {
         typedef typename internal::function_body<T6, tag_value> *f6_p;
         typedef typename internal::function_body<T7, tag_value> *f7_p;
         typedef typename internal::function_body<T8, tag_value> *f8_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7, typename B8>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7, B8 b8) : base_type(g,
-                func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3),
-                    new internal::function_body_leaf<T4, tag_value, B4>(b4),
-                    new internal::function_body_leaf<T5, tag_value, B5>(b5),
-                    new internal::function_body_leaf<T6, tag_value, B6>(b6),
-                    new internal::function_body_leaf<T7, tag_value, B7>(b7),
-                    new internal::function_body_leaf<T8, tag_value, B8>(b8)
+        template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
+                 typename Body5, typename Body6, typename Body7, typename Body8>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
+                Body5 body5, Body6 body6, Body7 body7, Body8 body8) : base_type(g, func_initializer_type(
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3),
+                    new internal::function_body_leaf<T4, tag_value, Body4>(body4),
+                    new internal::function_body_leaf<T5, tag_value, Body5>(body5),
+                    new internal::function_body_leaf<T6, tag_value, Body6>(body6),
+                    new internal::function_body_leaf<T7, tag_value, Body7>(body7),
+                    new internal::function_body_leaf<T8, tag_value, Body8>(body8)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 10
     template<typename OutputTuple>
-    class unfolded_join_node<10,tag_matching_port,OutputTuple,tag_matching> : public internal::join_node_base<tag_matching,
-        std::tuple<
-                tag_matching_port<typename std::tuple_element<0,OutputTuple>::type>, 
-                tag_matching_port<typename std::tuple_element<1,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<2,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<3,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<4,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<5,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<6,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<7,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<8,OutputTuple>::type>,
-                tag_matching_port<typename std::tuple_element<9,OutputTuple>::type>
-            >, OutputTuple >
-                  {
-        typedef typename std::tuple_element<0, OutputTuple>::type T0;
-        typedef typename std::tuple_element<1, OutputTuple>::type T1;
-        typedef typename std::tuple_element<2, OutputTuple>::type T2;
-        typedef typename std::tuple_element<3, OutputTuple>::type T3;
-        typedef typename std::tuple_element<4, OutputTuple>::type T4;
-        typedef typename std::tuple_element<5, OutputTuple>::type T5;
-        typedef typename std::tuple_element<6, OutputTuple>::type T6;
-        typedef typename std::tuple_element<7, OutputTuple>::type T7;
-        typedef typename std::tuple_element<8, OutputTuple>::type T8;
-        typedef typename std::tuple_element<9, OutputTuple>::type T9;
+    class unfolded_join_node<10,tag_matching_port,OutputTuple,tag_matching> : public
+            join_base<10,tag_matching_port,OutputTuple,tag_matching>::type {
+        typedef typename tbb::flow::tuple_element<0, OutputTuple>::type T0;
+        typedef typename tbb::flow::tuple_element<1, OutputTuple>::type T1;
+        typedef typename tbb::flow::tuple_element<2, OutputTuple>::type T2;
+        typedef typename tbb::flow::tuple_element<3, OutputTuple>::type T3;
+        typedef typename tbb::flow::tuple_element<4, OutputTuple>::type T4;
+        typedef typename tbb::flow::tuple_element<5, OutputTuple>::type T5;
+        typedef typename tbb::flow::tuple_element<6, OutputTuple>::type T6;
+        typedef typename tbb::flow::tuple_element<7, OutputTuple>::type T7;
+        typedef typename tbb::flow::tuple_element<8, OutputTuple>::type T8;
+        typedef typename tbb::flow::tuple_element<9, OutputTuple>::type T9;
     public:
-        typedef typename std::tuple< tag_matching_port<T0>, tag_matching_port<T1>, tag_matching_port<T2>,
-                tag_matching_port<T3>, tag_matching_port<T4>, tag_matching_port<T5>, tag_matching_port<T6>,
-                tag_matching_port<T7>, tag_matching_port<T8>, tag_matching_port<T9> > input_ports_tuple_type;
+        typedef typename wrap_tuple_elements<10, tag_matching_port, OutputTuple>::type input_ports_type;
         typedef OutputTuple output_type;
     private:
-        typedef join_node_base<tag_matching, input_ports_tuple_type, output_type > base_type;
+        typedef join_node_base<tag_matching, input_ports_type, output_type > base_type;
         typedef typename internal::function_body<T0, tag_value> *f0_p;
         typedef typename internal::function_body<T1, tag_value> *f1_p;
         typedef typename internal::function_body<T2, tag_value> *f2_p;
@@ -1671,32 +1711,33 @@ namespace internal {
         typedef typename internal::function_body<T7, tag_value> *f7_p;
         typedef typename internal::function_body<T8, tag_value> *f8_p;
         typedef typename internal::function_body<T9, tag_value> *f9_p;
-        typedef typename std::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p, f9_p > func_initializer_type;
+        typedef typename tbb::flow::tuple< f0_p, f1_p, f2_p, f3_p, f4_p, f5_p, f6_p, f7_p, f8_p, f9_p > func_initializer_type;
     public:
-        template<typename B0, typename B1, typename B2, typename B3, typename B4, typename B5, typename B6, typename B7, typename B8, typename B9>
-        unfolded_join_node(graph &g, B0 b0, B1 b1, B2 b2, B3 b3, B4 b4, B5 b5, B6 b6, B7 b7, B8 b8, B9 b9) : base_type(g,
-                func_initializer_type(
-                    new internal::function_body_leaf<T0, tag_value, B0>(b0),
-                    new internal::function_body_leaf<T1, tag_value, B1>(b1),
-                    new internal::function_body_leaf<T2, tag_value, B2>(b2),
-                    new internal::function_body_leaf<T3, tag_value, B3>(b3),
-                    new internal::function_body_leaf<T4, tag_value, B4>(b4),
-                    new internal::function_body_leaf<T5, tag_value, B5>(b5),
-                    new internal::function_body_leaf<T6, tag_value, B6>(b6),
-                    new internal::function_body_leaf<T7, tag_value, B7>(b7),
-                    new internal::function_body_leaf<T8, tag_value, B8>(b8),
-                    new internal::function_body_leaf<T9, tag_value, B9>(b9)
+        template<typename Body0, typename Body1, typename Body2, typename Body3, typename Body4,
+            typename Body5, typename Body6, typename Body7, typename Body8, typename Body9>
+        unfolded_join_node(graph &g, Body0 body0, Body1 body1, Body2 body2, Body3 body3, Body4 body4,
+                Body5 body5, Body6 body6, Body7 body7, Body8 body8, Body9 body9) : base_type(g, func_initializer_type(
+                    new internal::function_body_leaf<T0, tag_value, Body0>(body0),
+                    new internal::function_body_leaf<T1, tag_value, Body1>(body1),
+                    new internal::function_body_leaf<T2, tag_value, Body2>(body2),
+                    new internal::function_body_leaf<T3, tag_value, Body3>(body3),
+                    new internal::function_body_leaf<T4, tag_value, Body4>(body4),
+                    new internal::function_body_leaf<T5, tag_value, Body5>(body5),
+                    new internal::function_body_leaf<T6, tag_value, Body6>(body6),
+                    new internal::function_body_leaf<T7, tag_value, Body7>(body7),
+                    new internal::function_body_leaf<T8, tag_value, Body8>(body8),
+                    new internal::function_body_leaf<T9, tag_value, Body9>(body9)
                     ) ) {}
         unfolded_join_node(const unfolded_join_node &other) : base_type(other) {}
     };
+#endif
 
     //! templated function to refer to input ports of the join node
     template<size_t N, typename JNT>
-    typename std::tuple_element<N, typename JNT::input_ports_tuple_type>::type &input_port(JNT &jn) {
-        return std::get<N>(jn.inputs());
+    typename tbb::flow::tuple_element<N, typename JNT::input_ports_type>::type &input_port(JNT &jn) {
+        return tbb::flow::get<N>(jn.input_ports());
     }
 
-} 
-
+}
 #endif // __TBB__flow_graph_join_impl_H
 
index de2fe40f8a0141299ac8b61f6ae52144ad8e9146..837d8344931c76c4442a69f85bff3a476d4009ae 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__flow_graph_node_impl_H
@@ -59,19 +51,28 @@ namespace internal {
     //  call and any handling of the result.
     template< typename Input, typename A, typename ImplType >
     class function_input_base : public receiver<Input>, tbb::internal::no_assign {
-        typedef sender<Input> predecessor_type;
         enum op_stat {WAIT=0, SUCCEEDED, FAILED};
-        enum op_type {reg_pred, rem_pred, app_body, tryput, try_fwd};
+        enum op_type {reg_pred, rem_pred, app_body, try_fwd, tryput_bypass, app_body_bypass
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            , add_blt_pred, del_blt_pred,
+            blt_pred_cnt, blt_pred_cpy   // create vector copies of preds and succs
+#endif 
+        };
         typedef function_input_base<Input, A, ImplType> my_class;
         
     public:
 
         //! The input type of this receiver
         typedef Input input_type;
-        
+        typedef sender<Input> predecessor_type;
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<predecessor_type *> predecessor_vector_type;
+#endif
+
         //! Constructor for function_input_base
         function_input_base( graph &g, size_t max_concurrency, function_input_queue<input_type,A> *q = NULL )
-            : my_root_task(g.root_task()), my_max_concurrency(max_concurrency), my_concurrency(0),
+            : my_graph(g), my_max_concurrency(max_concurrency), my_concurrency(0),
               my_queue(q), forwarder_busy(false) {
             my_predecessors.set_owner(this);
             my_aggregator.initialize_handler(my_handler(this));
@@ -80,7 +81,7 @@ namespace internal {
         //! Copy constructor
         function_input_base( const function_input_base& src, function_input_queue<input_type,A> *q = NULL ) :
             receiver<Input>(), tbb::internal::no_assign(),
-            my_root_task( src.my_root_task), my_max_concurrency(src.my_max_concurrency),
+            my_graph(src.my_graph), my_max_concurrency(src.my_max_concurrency),
             my_concurrency(0), my_queue(q), forwarder_busy(false)
         {
             my_predecessors.set_owner(this);
@@ -92,18 +93,20 @@ namespace internal {
             if ( my_queue ) delete my_queue;
         }
         
-        //! Put to the node
-        virtual bool try_put( const input_type &t ) {
+        //! Put to the node, returning a task if available
+        virtual task * try_put_task( const input_type &t ) {
            if ( my_max_concurrency == 0 ) {
-               spawn_body_task( t );
-               return true;
+               return create_body_task( t );
            } else {
-               my_operation op_data(t, tryput);
+               my_operation op_data(t, tryput_bypass);
                my_aggregator.execute(&op_data);
-               return op_data.status == SUCCEEDED;
+               if(op_data.status == SUCCEEDED ) {
+                   return op_data.bypass_t;
+               }
+               return NULL;
            }
         }
-        
+
         //! Adds src to the list of cached predecessors.
         /* override */ bool register_predecessor( predecessor_type &src ) {
             my_operation op_data(reg_pred);
@@ -120,18 +123,62 @@ namespace internal {
             return true;
         }
 
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        //! Adds to list of predecessors added by make_edge
+        /*override*/ void internal_add_built_predecessor( predecessor_type &src) {
+            my_operation op_data(add_blt_pred);
+            op_data.r = &src;
+            my_aggregator.execute(&op_data);
+        }
+
+        //! removes from to list of predecessors (used by remove_edge)
+        /*override*/ void internal_delete_built_predecessor( predecessor_type &src) {
+            my_operation op_data(del_blt_pred);
+            op_data.r = &src;
+            my_aggregator.execute(&op_data);
+        }
+
+        /*override*/ size_t predecessor_count() {
+            my_operation op_data(blt_pred_cnt);
+            my_aggregator.execute(&op_data);
+            return op_data.cnt_val;
+        }
+
+        /*override*/ void copy_predecessors(predecessor_vector_type &v) {
+            my_operation op_data(blt_pred_cpy);
+            op_data.predv = &v;
+            my_aggregator.execute(&op_data);
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
     protected:
 
-        task *my_root_task;
+        void reset_function_input_base( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            my_concurrency = 0;
+            if(my_queue) {
+                my_queue->reset();
+            }
+            reset_receiver(__TBB_PFG_RESET_ARG(f));
+            forwarder_busy = false;
+        }
+
+        graph& my_graph;
         const size_t my_max_concurrency;
         size_t my_concurrency;
         function_input_queue<input_type, A> *my_queue;
         predecessor_cache<input_type, null_mutex > my_predecessors;
         
+        /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            my_predecessors.reset(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            __TBB_ASSERT(!(f & rf_extract) || my_predecessors.empty(), "function_input_base reset failed");
+#endif
+        }
+
     private:
 
-        friend class apply_body_task< my_class, input_type >;
-        friend class forward_task< my_class >;
+        friend class apply_body_task_bypass< my_class, input_type >;
+        friend class forward_task_bypass< my_class >;
         
         class my_operation : public aggregated_operation< my_operation > {
         public:
@@ -139,7 +186,12 @@ namespace internal {
             union {
                 input_type *elem;
                 predecessor_type *r;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                size_t cnt_val;
+                predecessor_vector_type *predv;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
             };
+            tbb::task *bypass_t;
             my_operation(const input_type& e, op_type t) :
                 type(char(t)), elem(const_cast<input_type*>(&e)) {}
             my_operation(op_type t) : type(char(t)), r(NULL) {}
@@ -185,28 +237,71 @@ namespace internal {
                         }
                     }
                     break;
-                case tryput: internal_try_put(tmp);  break;
+                case app_body_bypass: {
+                        task * new_task = NULL;
+                        __TBB_ASSERT(my_max_concurrency != 0, NULL);
+                        --my_concurrency;
+                        if (my_concurrency<my_max_concurrency) {
+                            input_type i;
+                            bool item_was_retrieved = false;
+                            if ( my_queue )
+                                item_was_retrieved = my_queue->pop(i);
+                            else 
+                                item_was_retrieved = my_predecessors.get_item(i);
+                            if (item_was_retrieved) {
+                                ++my_concurrency;
+                                new_task = create_body_task(i);
+                            }
+                        }
+                        tmp->bypass_t = new_task;
+                        __TBB_store_with_release(tmp->status, SUCCEEDED);
+                    }
+                    break;
+                case tryput_bypass: internal_try_put_task(tmp);  break;
                 case try_fwd: internal_forward(tmp);  break;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+                case add_blt_pred: {
+                         my_predecessors.internal_add_built_predecessor(*(tmp->r));
+                        __TBB_store_with_release(tmp->status, SUCCEEDED);
+                    }
+                    break;
+                case del_blt_pred:
+                    my_predecessors.internal_delete_built_predecessor(*(tmp->r));
+                    __TBB_store_with_release(tmp->status, SUCCEEDED);
+                    break;
+                case blt_pred_cnt:
+                    tmp->cnt_val = my_predecessors.predecessor_count();
+                    __TBB_store_with_release(tmp->status, SUCCEEDED);
+                    break;
+                case blt_pred_cpy:
+                    my_predecessors.copy_predecessors( *(tmp->predv) );
+                    __TBB_store_with_release(tmp->status, SUCCEEDED);
+                    break;
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
                 }
             }
         }
         
-        //! Put to the node
-        void internal_try_put(my_operation *op) {
+        //! Put to the node, but return the task instead of enqueueing it
+        void internal_try_put_task(my_operation *op) {
             __TBB_ASSERT(my_max_concurrency != 0, NULL);
             if (my_concurrency < my_max_concurrency) {
                ++my_concurrency;
-               spawn_body_task(*(op->elem));
+               task * new_task = create_body_task(*(op->elem));
+               op->bypass_t = new_task;
                __TBB_store_with_release(op->status, SUCCEEDED);
            } else if ( my_queue && my_queue->push(*(op->elem)) ) { 
+               op->bypass_t = SUCCESSFULLY_ENQUEUED;
                __TBB_store_with_release(op->status, SUCCEEDED);
            } else {
+               op->bypass_t = NULL;
                __TBB_store_with_release(op->status, FAILED);
            }
         }
         
         //! Tries to spawn bodies if available and if concurrency allows
         void internal_forward(my_operation *op) {
+            op->bypass_t = NULL;
             if (my_concurrency<my_max_concurrency || !my_max_concurrency) {
                 input_type i;
                 bool item_was_retrieved = false;
@@ -216,8 +311,8 @@ namespace internal {
                     item_was_retrieved = my_predecessors.get_item(i);
                 if (item_was_retrieved) {
                     ++my_concurrency;
+                    op->bypass_t = create_body_task(i);
                     __TBB_store_with_release(op->status, SUCCEEDED);
-                    spawn_body_task(i);
                     return;
                 }
             }
@@ -226,31 +321,75 @@ namespace internal {
         }
         
         //! Applies the body to the provided input
+        //  then decides if more work is available 
         void apply_body( input_type &i ) {
-            static_cast<ImplType *>(this)->apply_body_impl(i);
+            task *new_task = apply_body_bypass(i);
+            if(!new_task) return;
+            if(new_task == SUCCESSFULLY_ENQUEUED) return;
+            FLOW_SPAWN(*new_task);
+            return;
+        }
+        
+        //! Applies the body to the provided input
+        //  then decides if more work is available 
+        task * apply_body_bypass( input_type &i ) {
+            task * new_task = static_cast<ImplType *>(this)->apply_body_impl_bypass(i);
             if ( my_max_concurrency != 0 ) {
-                my_operation op_data(app_body);
+                my_operation op_data(app_body_bypass);  // tries to pop an item or get_item, enqueues another apply_body
                 my_aggregator.execute(&op_data);
+                tbb::task *ttask = op_data.bypass_t;
+                new_task = combine_tasks(new_task, ttask);
             }
+            return new_task;
         }
         
+        //! allocates a task to call apply_body( input )
+        inline task * create_body_task( const input_type &input ) {
+            
+            task* tp = my_graph.root_task();
+            return (tp) ?
+                new(task::allocate_additional_child_of(*tp))
+                    apply_body_task_bypass < my_class, input_type >(*this, input) :
+                NULL;
+        }
+
        //! Spawns a task that calls apply_body( input )
        inline void spawn_body_task( const input_type &input ) {
-           task::enqueue(*new(task::allocate_additional_child_of(*my_root_task)) apply_body_task< my_class, input_type >(*this, input));
+           task* tp = create_body_task(input);
+           // tp == NULL => g.reset(), which shouldn't occur in concurrent context
+           if(tp) {
+               FLOW_SPAWN(*tp);
+           }
        }
         
        //! This is executed by an enqueued task, the "forwarder"
-       void forward() {
+       task *forward_task() {
            my_operation op_data(try_fwd);
+           task *rval = NULL;
            do {
                op_data.status = WAIT;
                my_aggregator.execute(&op_data);
+               if(op_data.status == SUCCEEDED) {
+                   tbb::task *ttask = op_data.bypass_t;
+                   rval = combine_tasks(rval, ttask);
+               }
            } while (op_data.status == SUCCEEDED);
+           return rval;
        }
         
+       inline task *create_forward_task() {
+           task* tp = my_graph.root_task();
+           return (tp) ?
+               new(task::allocate_additional_child_of(*tp)) forward_task_bypass< my_class >(*this) :
+               NULL;
+       }
+
        //! Spawns a task that calls forward()
        inline void spawn_forward_task() {
-           task::enqueue(*new(task::allocate_additional_child_of(*my_root_task)) forward_task< my_class >(*this));
+           task* tp = create_forward_task();
+           if(tp) {
+               FLOW_SPAWN(*tp);
+           }
        }
     };  // function_input_base
 
@@ -289,72 +428,137 @@ namespace internal {
             return dynamic_cast< internal::function_body_leaf<input_type, output_type, Body> & >(body_ref).get_body(); 
         } 
 
-        void apply_body_impl( const input_type &i) {
-            successors().try_put( (*my_body)(i) );
+        task * apply_body_impl_bypass( const input_type &i) {
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+            // There is an extra copied needed to capture the
+            // body execution without the try_put
+            tbb::internal::fgt_begin_body( my_body );
+            output_type v = (*my_body)(i);
+            tbb::internal::fgt_end_body( my_body );
+            task * new_task = successors().try_put_task( v );
+#else       
+            task * new_task = successors().try_put_task( (*my_body)(i) );
+#endif
+            return new_task;
         }
 
     protected:
+
+        void reset_function_input(__TBB_PFG_RESET_ARG(reset_flags f)) {
+            base_type::reset_function_input_base(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            if(f & rf_reset_bodies) my_body->reset_body();
+#endif
+        }
+
         function_body<input_type, output_type> *my_body;
         virtual broadcast_cache<output_type > &successors() = 0;
 
+    };  // function_input
+
+
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+    // helper templates to reset the successor edges of the output ports of an multifunction_node
+    template<int N>
+    struct reset_element {
+        template<typename P>
+        static void reset_this(P &p, reset_flags f) {
+            (void)tbb::flow::get<N-1>(p).successors().reset(f);
+            reset_element<N-1>::reset_this(p, f);
+        }
+        template<typename P>
+        static bool this_empty(P &p) {
+            if(tbb::flow::get<N-1>(p).successors().empty()) 
+                return reset_element<N-1>::this_empty(p);
+            return false;
+        }
     };
 
-#if TBB_PREVIEW_GRAPH_NODES
+    template<>
+    struct reset_element<1> {
+        template<typename P>
+        static void reset_this(P &p, reset_flags f) {
+            (void)tbb::flow::get<0>(p).successors().reset(f);
+        }
+        template<typename P>
+        static bool this_empty(P &p) {
+            return tbb::flow::get<0>(p).successors().empty();
+        }
+    };
+#endif
+
     //! Implements methods for a function node that takes a type Input as input
     //  and has a tuple of output ports specified.  
     template< typename Input, typename OutputPortSet, typename A>
-    class multioutput_function_input : public function_input_base<Input, A, multioutput_function_input<Input,OutputPortSet,A> > {
+    class multifunction_input : public function_input_base<Input, A, multifunction_input<Input,OutputPortSet,A> > {
     public:
+        static const int N = tbb::flow::tuple_size<OutputPortSet>::value;
         typedef Input input_type;
         typedef OutputPortSet output_ports_type;
-        typedef multioutput_function_input<Input,OutputPortSet,A> my_class;
+        typedef multifunction_input<Input,OutputPortSet,A> my_class;
         typedef function_input_base<Input, A, my_class> base_type;
         typedef function_input_queue<input_type, A> input_queue_type;
 
 
         // constructor
         template<typename Body>
-        multioutput_function_input( 
+        multifunction_input( 
                 graph &g, 
                 size_t max_concurrency, 
                 Body& body,
                 function_input_queue<input_type,A> *q = NULL ) :
             base_type(g, max_concurrency, q),
-            my_body( new internal::multioutput_function_body_leaf<input_type, output_ports_type, Body>(body) ) {
+            my_body( new internal::multifunction_body_leaf<input_type, output_ports_type, Body>(body) ) {
         }
 
         //! Copy constructor
-        multioutput_function_input( const multioutput_function_input& src, input_queue_type *q = NULL ) : 
+        multifunction_input( const multifunction_input& src, input_queue_type *q = NULL ) : 
                 base_type(src, q),
                 my_body( src.my_body->clone() ) {
         }
 
-        ~multioutput_function_input() {
+        ~multifunction_input() {
             delete my_body;
         }
 
         template< typename Body >
         Body copy_function_object() {
-            internal::multioutput_function_body<input_type, output_ports_type> &body_ref = *this->my_body;
-            return dynamic_cast< internal::multioutput_function_body_leaf<input_type, output_ports_type, Body> & >(body_ref).get_body(); 
+            internal::multifunction_body<input_type, output_ports_type> &body_ref = *this->my_body;
+            return dynamic_cast< internal::multifunction_body_leaf<input_type, output_ports_type, Body> & >(body_ref).get_body(); 
         } 
 
-        void apply_body_impl( const input_type &i) {
+        // for multifunction nodes we do not have a single successor as such.  So we just tell
+        // the task we were successful.
+        task * apply_body_impl_bypass( const input_type &i) {
+            tbb::internal::fgt_begin_body( my_body );
             (*my_body)(i, my_output_ports);
+            tbb::internal::fgt_end_body( my_body );
+            task * new_task = SUCCESSFULLY_ENQUEUED;
+            return new_task;
         }
 
         output_ports_type &output_ports(){ return my_output_ports; }
 
     protected:
-        multioutput_function_body<input_type, output_ports_type> *my_body;
+
+        /*override*/void reset(__TBB_PFG_RESET_ARG(reset_flags f)) { 
+            base_type::reset_function_input_base(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            reset_element<N>::reset_this(my_output_ports, f);
+            if(f & rf_reset_bodies) my_body->reset_body();
+            __TBB_ASSERT(!(f & rf_extract) || reset_element<N>::this_empty(my_output_ports), "multifunction_node reset failed");
+#endif
+        }
+
+        multifunction_body<input_type, output_ports_type> *my_body;
         output_ports_type my_output_ports;
 
-    };
+    };  // multifunction_input
 
-    // template to refer to an output port of a multioutput_function_node
+    // template to refer to an output port of a multifunction_node
     template<size_t N, typename MOP>
-    typename std::tuple_element<N, typename MOP::output_ports_type>::type &output_port(MOP &op) {
-        return std::get<N>(op.output_ports()); 
+    typename tbb::flow::tuple_element<N, typename MOP::output_ports_type>::type &output_port(MOP &op) {
+        return tbb::flow::get<N>(op.output_ports()); 
     }
 
 // helper structs for split_node
@@ -362,7 +566,7 @@ namespace internal {
     struct emit_element {
         template<typename T, typename P>
         static void emit_this(const T &t, P &p) {
-            std::get<N-1>(p).put(std::get<N-1>(t));
+            (void)tbb::flow::get<N-1>(p).try_put(tbb::flow::get<N-1>(t));
             emit_element<N-1>::emit_this(t,p);
         }
     };
@@ -371,10 +575,9 @@ namespace internal {
     struct emit_element<1> {
         template<typename T, typename P>
         static void emit_this(const T &t, P &p) {
-            std::get<0>(p).put(std::get<0>(t));
+            (void)tbb::flow::get<0>(p).try_put(tbb::flow::get<0>(t));
         }
     };
-#endif  // TBB_PREVIEW_GRAPH_NODES
 
     //! Implements methods for an executable node that takes continue_msg as input
     template< typename Output >
@@ -389,16 +592,20 @@ namespace internal {
         
         template< typename Body >
         continue_input( graph &g, Body& body )
-            : my_root_task(g.root_task()), 
+            : my_graph_ptr(&g), 
              my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { }
         
         template< typename Body >
         continue_input( graph &g, int number_of_predecessors, Body& body )
-            : continue_receiver( number_of_predecessors ), my_root_task(g.root_task()), 
+            : continue_receiver( number_of_predecessors ), my_graph_ptr(&g), 
              my_body( new internal::function_body_leaf< input_type, output_type, Body>(body) ) { }
 
         continue_input( const continue_input& src ) : continue_receiver(src), 
-            my_root_task(src.my_root_task), my_body( src.my_body->clone() ) {}
+            my_graph_ptr(src.my_graph_ptr), my_body( src.my_body->clone() ) {}
+
+        ~continue_input() {
+            delete my_body;
+        }
 
         template< typename Body >
         Body copy_function_object() {
@@ -406,34 +613,61 @@ namespace internal {
             return dynamic_cast< internal::function_body_leaf<input_type, output_type, Body> & >(body_ref).get_body(); 
         } 
 
+        /*override*/void reset_receiver( __TBB_PFG_RESET_ARG(reset_flags f)) {
+            continue_receiver::reset_receiver(__TBB_PFG_RESET_ARG(f));
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+            if(f & rf_reset_bodies) my_body->reset_body();
+#endif
+        }
+
     protected:
         
-        task *my_root_task;
+        graph* my_graph_ptr;
         function_body<input_type, output_type> *my_body;
         
         virtual broadcast_cache<output_type > &successors() = 0; 
         
-        friend class apply_body_task< continue_input< Output >, continue_msg >;
+        friend class apply_body_task_bypass< continue_input< Output >, continue_msg >;
         
         //! Applies the body to the provided input
-        /* override */ void apply_body( input_type ) {
-            successors().try_put( (*my_body)( continue_msg() ) );
+        /* override */ task *apply_body_bypass( input_type ) {
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+            // There is an extra copied needed to capture the
+            // body execution without the try_put
+            tbb::internal::fgt_begin_body( my_body );
+            output_type v = (*my_body)( continue_msg() );
+            tbb::internal::fgt_end_body( my_body );
+            return successors().try_put_task( v );
+#else   
+            return successors().try_put_task( (*my_body)( continue_msg() ) );
+#endif
         }
         
         //! Spawns a task that applies the body
-        /* override */ void execute( ) {
-            task::enqueue( * new ( task::allocate_additional_child_of( *my_root_task ) ) 
-               apply_body_task< continue_input< Output >, continue_msg >( *this, continue_msg() ) ); 
+        /* override */ task *execute( ) {
+            task* tp = my_graph_ptr->root_task();
+            return (tp) ?
+                new ( task::allocate_additional_child_of( *tp ) ) 
+                    apply_body_task_bypass< continue_input< Output >, continue_msg >( *this, continue_msg() ) :
+                NULL;
         }
 
-    };
+    };  // continue_input
         
     //! Implements methods for both executable and function nodes that puts Output to its successors
     template< typename Output >
     class function_output : public sender<Output> {
     public:
         
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        template<int N> friend struct reset_element;
+#endif
         typedef Output output_type;
+        typedef receiver<output_type> successor_type;
+        typedef broadcast_cache<output_type> broadcast_cache_type;
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        typedef std::vector<successor_type *> successor_vector_type;
+#endif
         
         function_output() { my_successors.set_owner(this); }
         function_output(const function_output & /*other*/) : sender<output_type>() {
@@ -452,21 +686,56 @@ namespace internal {
             return true;
         }
 
-        // for multioutput_function_node.  The function_body that implements
+#if TBB_PREVIEW_FLOW_GRAPH_FEATURES
+        /*override*/ void internal_add_built_successor( receiver<output_type> &r) {
+            successors().internal_add_built_successor( r );
+        }
+
+        /*override*/ void internal_delete_built_successor( receiver<output_type> &r) {
+            successors().internal_delete_built_successor( r );
+        }
+
+        /*override*/ size_t successor_count() {
+            return successors().successor_count();
+        }
+
+        /*override*/ void  copy_successors( successor_vector_type &v) {
+            successors().copy_successors(v);
+        }
+#endif  /* TBB_PREVIEW_FLOW_GRAPH_FEATURES */
+
+        // for multifunction_node.  The function_body that implements
         // the node will have an input and an output tuple of ports.  To put
         // an item to a successor, the body should
         //
-        //    get<I>(output_ports).put(output_value);
+        //    get<I>(output_ports).try_put(output_value);
         //
-        // successors must always accept (for instance, a queue_node) or items
-        // may be dropped.
-        void put(const output_type &i) { my_successors.try_put(i); }
+        // return value will be bool returned from successors.try_put.
+        task *try_put_task(const output_type &i) { return my_successors.try_put_task(i); }
           
     protected:
-        broadcast_cache<output_type> my_successors;
-        broadcast_cache<output_type > &successors() { return my_successors; } 
+        broadcast_cache_type my_successors;
+        broadcast_cache_type &successors() { return my_successors; } 
         
-    };
+    };  // function_output
+
+    template< typename Output >
+    class multifunction_output : public function_output<Output> {
+    public:
+        typedef Output output_type;
+        typedef function_output<output_type> base_type;
+        using base_type::my_successors;
+        
+        multifunction_output() : base_type() {my_successors.set_owner(this);}
+        multifunction_output( const multifunction_output &/*other*/) : base_type() { my_successors.set_owner(this); }
+
+        bool try_put(const output_type &i) {
+            task *res = my_successors.try_put_task(i);
+            if(!res) return false;
+            if(res != SUCCESSFULLY_ENQUEUED) FLOW_SPAWN(*res);
+            return true;
+        }
+    };  // multifunction_output
 
 }  // internal
 
diff --git a/dependencies64/tbb/include/tbb/internal/_flow_graph_or_impl.h b/dependencies64/tbb/include/tbb/internal/_flow_graph_or_impl.h
deleted file mode 100644 (file)
index f17f536..0000000
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
-*/
-
-#ifndef __TBB__flow_graph_or_impl_H
-#define __TBB__flow_graph_or_impl_H
-
-#ifndef __TBB_flow_graph_H
-#error Do not #include this internal file directly; use public TBB headers instead.
-#endif
-
-#if TBB_PREVIEW_GRAPH_NODES
-#include "tbb/internal/_flow_graph_types_impl.h"
-
-namespace internal {
-
-    // Output of the or_node is a struct containing a std::tuple, and will be of
-    // the form
-    //
-    //  struct {
-    //     size_t indx;
-    //     tuple_types result;
-    //  };
-    //
-    //  where the value of indx will indicate which result was put to the
-    //  successor. So if oval is the output to the successor, indx == 0 
-    //  means std::get<0>(oval.result) is the output, and so on.
-    //
-    //  tuple_types is the tuple that specified the possible outputs (and
-    //  the corresponding inputs to the or_node.)
-    //
-    //  the types of each element are represented by tuple_types, a typedef
-    //  in the or_node.  So the 2nd type in the union that is the
-    //  output type for an or_node OrType is
-    //
-    //      std::tuple_element<1,OrType::tuple_types>::type
-
-    // the struct has an OutputTuple default constructed, with element index assigned
-    // the actual output value.
-    template<typename OutputTuple>
-    struct or_output_type {
-        typedef OutputTuple tuple_types;
-        typedef struct {
-            size_t indx;
-            OutputTuple result;
-        } type;
-    };
-
-    template<typename TupleTypes,int N>
-    struct or_item_helper {
-        template<typename OutputType>
-        static inline void create_output_value(OutputType &o, void *v) {
-            o.indx = N;
-            std::get<N>(o.result) = *(reinterpret_cast<typename std::tuple_element<N, TupleTypes>::type *>(v));
-        }
-    };
-
-    template<typename TupleTypes,int N>
-    struct or_helper {
-        template<typename OutputType>
-        static inline void create_output(OutputType &o, size_t i, void* v) {
-            if(i == N-1) {
-                or_item_helper<TupleTypes,N-1>::create_output_value(o,v);
-            }
-            else
-                or_helper<TupleTypes,N-1>::create_output(o,i,v);
-        }
-        template<typename PortTuple, typename PutBase>
-        static inline void set_or_node_pointer(PortTuple &my_input, PutBase *p) {
-            std::get<N-1>(my_input).set_up(p, N-1);
-            or_helper<TupleTypes,N-1>::set_or_node_pointer(my_input, p);
-        }
-    };
-
-    template<typename TupleTypes>
-    struct or_helper<TupleTypes,1> {
-        template<typename OutputType>
-        static inline void create_output(OutputType &o, size_t i, void* v) {
-            if(i == 0) {
-                or_item_helper<TupleTypes,0>::create_output_value(o,v);
-            }
-        }
-        template<typename PortTuple, typename PutBase>
-        static inline void set_or_node_pointer(PortTuple &my_input, PutBase *p) {
-            std::get<0>(my_input).set_up(p, 0);
-        }
-    };
-
-    struct put_base {
-        virtual bool try_put_with_index(size_t index, void *v) = 0;
-        virtual ~put_base() { }
-    };
-
-    template<typename T>
-    class or_input_port : public receiver<T> {
-    private:
-        size_t my_index;
-        put_base *my_or_node;
-    public:
-        void set_up(put_base *p, size_t i) { my_index = i; my_or_node = p; }
-        bool try_put(const T &v) {
-            return my_or_node->try_put_with_index(my_index, reinterpret_cast<void *>(const_cast<T*>(&v)));
-        }
-    };
-
-    template<typename InputTuple, typename OutputType, typename StructTypes>
-    class or_node_FE : public put_base {
-    public:
-        static const int N = std::tuple_size<InputTuple>::value;
-        typedef OutputType output_type;
-        typedef InputTuple input_type;
-
-        or_node_FE( ) {
-            or_helper<StructTypes,N>::set_or_node_pointer(my_inputs, this);
-        }
-
-        input_type &inputs() { return my_inputs; }
-    protected:
-        input_type my_inputs;
-    };
-
-    //! or_node_base
-    template<typename InputTuple, typename OutputType, typename StructTypes>
-    class or_node_base : public graph_node, public or_node_FE<InputTuple, OutputType,StructTypes>,
-                           public sender<OutputType> {
-    public:
-        static const size_t N = std::tuple_size<InputTuple>::value;
-        typedef OutputType output_type;
-        typedef StructTypes tuple_types;
-        typedef receiver<output_type> successor_type;
-        typedef or_node_FE<InputTuple, output_type,StructTypes> input_ports_type;
-
-    private:
-        // ----------- Aggregator ------------
-        enum op_type { reg_succ, rem_succ, try__put };
-        enum op_stat {WAIT=0, SUCCEEDED, FAILED};
-        typedef or_node_base<InputTuple,output_type,StructTypes> my_class;
-
-        class or_node_base_operation : public aggregated_operation<or_node_base_operation> {
-        public:
-            char type;
-            size_t indx;
-            union {
-                void *my_arg;
-                successor_type *my_succ;
-            };
-            or_node_base_operation(size_t i, const void* e, op_type t) :
-                type(char(t)), indx(i), my_arg(const_cast<void *>(e)) {}
-            or_node_base_operation(const successor_type &s, op_type t) : type(char(t)), 
-                my_succ(const_cast<successor_type *>(&s)) {}
-            or_node_base_operation(op_type t) : type(char(t)) {}
-        };
-
-        typedef internal::aggregating_functor<my_class, or_node_base_operation> my_handler;
-        friend class internal::aggregating_functor<my_class, or_node_base_operation>;
-        aggregator<my_handler, or_node_base_operation> my_aggregator;
-
-        void handle_operations(or_node_base_operation* op_list) {
-            or_node_base_operation *current;
-            while(op_list) {
-                current = op_list;
-                op_list = op_list->next;
-                switch(current->type) {
-
-                case reg_succ:
-                    my_successors.register_successor(*(current->my_succ));
-                    __TBB_store_with_release(current->status, SUCCEEDED);
-                    break;
-
-                case rem_succ:
-                    my_successors.remove_successor(*(current->my_succ));
-                    __TBB_store_with_release(current->status, SUCCEEDED);
-                    break;
-
-                case try__put:
-                    output_type oval;
-                    or_helper<tuple_types,N>::create_output(oval,current->indx,current->my_arg);
-                    bool res = my_successors.try_put(oval);
-                    __TBB_store_with_release(current->status, res ? SUCCEEDED : FAILED);
-                    break;
-                }
-            }
-        }
-        // ---------- end aggregator -----------
-    public:
-        or_node_base( ) : input_ports_type() {
-            my_successors.set_owner(this);
-            my_aggregator.initialize_handler(my_handler(this));
-        }
-
-        or_node_base( const or_node_base& /*other*/) : input_ports_type() {
-            my_successors.set_owner(this);
-            my_aggregator.initialize_handler(my_handler(this));
-        }
-
-        bool register_successor(successor_type &r) {
-            or_node_base_operation op_data(r, reg_succ);
-            my_aggregator.execute(&op_data);
-            return op_data.status == SUCCEEDED;
-        }
-
-        bool remove_successor( successor_type &r) {
-            or_node_base_operation op_data(r, rem_succ);
-            my_aggregator.execute(&op_data);
-            return op_data.status == SUCCEEDED;
-        }
-
-        bool try_put_with_index(size_t indx, void *v) {
-            or_node_base_operation op_data(indx, v, try__put);
-            my_aggregator.execute(&op_data);
-            return op_data.status == SUCCEEDED;
-        }
-
-    private:
-        broadcast_cache<output_type, null_rw_mutex> my_successors;
-    };
-
-    // type generators
-    template<typename OutputTuple>
-    struct or_types {
-        static const int N = std::tuple_size<OutputTuple>::value;
-        typedef typename wrap_tuple_elements<N,or_input_port,OutputTuple>::type input_ports_tuple_type;
-        typedef typename or_output_type<OutputTuple>::type output_type;
-        typedef internal::or_node_FE<input_ports_tuple_type,output_type,OutputTuple> or_FE_type;
-        typedef internal::or_node_base<input_ports_tuple_type, output_type, OutputTuple> or_base_type;
-    };
-
-    template<class OutputTuple>
-    class unfolded_or_node : public or_types<OutputTuple>::or_base_type {
-    public:
-        typedef typename or_types<OutputTuple>::input_ports_tuple_type input_ports_tuple_type;
-        typedef OutputTuple tuple_types;
-        typedef typename or_types<OutputTuple>::output_type output_type;
-    private:
-        typedef typename or_types<OutputTuple>::or_base_type base_type;
-    public:
-        unfolded_or_node() : base_type() {}
-    };
-
-
-} /* namespace internal */
-#endif  // TBB_PREVIEW_GRAPH_NODES
-
-#endif  /* __TBB__flow_graph_or_impl_H */
index 8b87fd14fe9a0bb34e4e30417b6c7a7ae674d49c..8c13eb59211757f54cb4aa45f2e396f232e2bdf2 100644 (file)
@@ -1,33 +1,25 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 // tagged buffer that can expand, and can support as many deletions as additions
-// list-based, with elements of list held in std::vector (for destruction management),
+// list-based, with elements of list held in array (for destruction management),
 // multiplicative hashing (like ets).  No synchronization built-in.
 //
 
 #error Do not #include this internal file directly; use public TBB headers instead.
 #endif
 
+// included in namespace tbb::flow::interface7::internal
+
+template<typename T, typename U, size_t NoTagMark>
+struct otherData {
+    T t;
+    U next;
+    otherData() : t(NoTagMark), next(NULL) {}
+};
+
 template<typename TagType, typename ValueType, size_t NoTagMark>
-struct buffer_element {
-    TagType t;
-    ValueType v;
-    buffer_element *next;
-    buffer_element() : t(NoTagMark), next(NULL) {}
+struct buffer_element_type {
+    // the second parameter below is void * because we can't forward-declare the type
+    // itself, so we just reinterpret_cast below.
+    typedef typename aligned_pair<ValueType, otherData<TagType, void *, NoTagMark> >::type type;
 };
 
 template
@@ -51,126 +51,175 @@ template
      typename TagType, 
      typename ValueType, 
      size_t   NoTagMark = 0,
-     typename Allocator=tbb::cache_aligned_allocator< buffer_element<TagType,ValueType,NoTagMark> >
+     typename Allocator=tbb::cache_aligned_allocator< typename buffer_element_type<TagType, ValueType, NoTagMark>::type >
     >
 class tagged_buffer {
 public:
     static const size_t INITIAL_SIZE = 8;  // initial size of the hash pointer table
     static const TagType NO_TAG = TagType(NoTagMark);
     typedef ValueType value_type;
-    typedef buffer_element<TagType,ValueType, NO_TAG> element_type;
+    typedef typename buffer_element_type<TagType, ValueType, NO_TAG>::type element_type;
     typedef value_type *pointer_type;
-    typedef std::vector<element_type, Allocator> list_array_type;
-    typedef typename Allocator::template rebind<element_type*>::other pointer_array_allocator_type;
-    typedef typename Allocator::template rebind<list_array_type>::other list_array_allocator;
+    typedef element_type *list_array_type;  // array we manage manually
+    typedef list_array_type *pointer_array_type;
+    typedef typename Allocator::template rebind<list_array_type>::other pointer_array_allocator_type;
+    typedef typename Allocator::template rebind<element_type>::other elements_array_allocator;
 private:
-
     size_t my_size;
     size_t nelements;
-    element_type** array;
-    std::vector<element_type, Allocator> *lists;
+    pointer_array_type pointer_array;    // pointer_array[my_size]
+    list_array_type elements_array;      // elements_array[my_size / 2]
     element_type* free_list;
 
     size_t mask() { return my_size - 1; }
 
-// #define ABYSMAL 1
     static size_t hash(TagType t) {
-#if ABYSMAL
-        return (size_t)1;
-#else
-#if __TBB_WORDSIZE == 4
-        return uintptr_t(t)*0x9E3779B9;
-#else
-        return uintptr_t(t)*0x9E3779B97F4A7C15;
-#endif
-#endif
+        return uintptr_t(t)*tbb::internal::select_size_t_constant<0x9E3779B9,0x9E3779B97F4A7C15ULL>::value;
     }
 
-    void set_up_free_list( element_type **p_free_list, list_array_type *la, size_t sz) {
+    void set_up_free_list( element_type **p_free_list, list_array_type la, size_t sz) {
         for(size_t i=0; i < sz - 1; ++i ) {  // construct free list
-            (*la)[i].next = &((*la)[i+1]);
-            (*la)[i].t = NO_TAG;
+            la[i].second.next = &(la[i+1]);
+            la[i].second.t = NO_TAG;
         }
-        (*la)[sz-1].next = NULL;
-        *p_free_list = &((*la)[0]);
+        la[sz-1].second.next = NULL;
+        *p_free_list = &(la[0]);
     }
 
+    // cleanup for exceptions
+    struct DoCleanup {
+        pointer_array_type *my_pa;
+        list_array_type *my_elements;
+        size_t my_size;
+
+        DoCleanup(pointer_array_type &pa, list_array_type &my_els, size_t sz) :
+            my_pa(&pa), my_elements(&my_els), my_size(sz) {  }
+        ~DoCleanup() {
+            if(my_pa) {
+                size_t dont_care = 0;
+                internal_free_buffer(*my_pa, *my_elements, my_size, dont_care);
+            }
+        }
+    };
+
+    // exception-safety requires we do all the potentially-throwing operations first
     void grow_array() {
-        // make the pointer array larger
-        element_type **new_array;
-        element_type **old_array = array;
-        size_t old_size = my_size;
-        my_size *=2;
-        new_array = pointer_array_allocator_type().allocate(my_size);
-        for(size_t i=0; i < my_size; ++i) new_array[i] = NULL;
-        list_array_type *new_list_array = new list_array_type(old_size, element_type(), Allocator());
-        set_up_free_list(&free_list, new_list_array, old_size );
-
-        for(size_t i=0; i < old_size; ++i) {
-            for( element_type* op = old_array[i]; op; op = op->next) {
-                internal_tagged_insert(new_array, my_size, op->t, op->v);
+        size_t new_size = my_size*2;
+        size_t new_nelements = nelements;  // internal_free_buffer zeroes this
+        list_array_type new_elements_array = NULL;
+        pointer_array_type new_pointer_array = NULL;
+        list_array_type new_free_list = NULL;
+        {
+            DoCleanup my_cleanup(new_pointer_array, new_elements_array, new_size);
+            new_elements_array = elements_array_allocator().allocate(my_size);
+            new_pointer_array = pointer_array_allocator_type().allocate(new_size);
+            for(size_t i=0; i < new_size; ++i) new_pointer_array[i] = NULL;
+            set_up_free_list(&new_free_list, new_elements_array, my_size );
+
+            for(size_t i=0; i < my_size; ++i) {
+                for( element_type* op = pointer_array[i]; op; op = (element_type *)(op->second.next)) {
+                    value_type *ov = reinterpret_cast<value_type *>(&(op->first));
+                    // could have std::move semantics
+                    internal_tagged_insert(new_pointer_array, new_size, new_free_list, op->second.t, *ov);
+                }
             }
+            my_cleanup.my_pa = NULL;
+            my_cleanup.my_elements = NULL;
         }
-        pointer_array_allocator_type().deallocate(old_array, old_size);
 
-        delete lists;  // destroy and deallocate instead
-        array = new_array;
-        lists = new_list_array;
+        internal_free_buffer(pointer_array, elements_array, my_size, nelements);
+        free_list = new_free_list;
+        pointer_array = new_pointer_array;
+        elements_array = new_elements_array;
+        my_size = new_size;
+        nelements = new_nelements;
     }
 
-    void internal_tagged_insert( element_type **ar, size_t sz, TagType t, value_type v) {
-        size_t l_mask = sz-1;
+    // v should have perfect forwarding if std::move implemented.
+    // we use this method to move elements in grow_array, so can't use class fields
+    void internal_tagged_insert( element_type **p_pointer_array, size_t p_sz, list_array_type &p_free_list,
+            const TagType t, const value_type &v) {
+        size_t l_mask = p_sz-1;
         size_t h = hash(t) & l_mask;
-        __TBB_ASSERT(free_list, "Error: free list not set up.");
-        element_type* my_elem = free_list; free_list = free_list->next;
-        my_elem->t = t;
-        my_elem->v = v;
-        my_elem->next = ar[h];
-        ar[h] = my_elem;
+        __TBB_ASSERT(p_free_list, "Error: free list not set up.");
+        element_type* my_elem = p_free_list; p_free_list = (element_type *)(p_free_list->second.next);
+        my_elem->second.t = t;
+        (void) new(&(my_elem->first)) value_type(v);
+        my_elem->second.next = p_pointer_array[h];
+        p_pointer_array[h] = my_elem;
+    }
+
+    void internal_initialize_buffer() {
+        pointer_array = pointer_array_allocator_type().allocate(my_size);
+        for(size_t i = 0; i < my_size; ++i) pointer_array[i] = NULL;
+        elements_array = elements_array_allocator().allocate(my_size / 2);
+        set_up_free_list(&free_list, elements_array, my_size / 2);
+    }
+
+    // made static so an enclosed class can use to properly dispose of the internals
+    static void internal_free_buffer( pointer_array_type &pa, list_array_type &el, size_t &sz, size_t &ne ) {
+        if(pa) {
+            for(size_t i = 0; i < sz; ++i ) {
+                element_type *p_next;
+                for( element_type *p = pa[i]; p; p = p_next) {
+                    p_next = (element_type *)p->second.next;
+                    value_type *vp = reinterpret_cast<value_type *>(&(p->first));
+                    vp->~value_type();
+                }
+            }
+            pointer_array_allocator_type().deallocate(pa, sz); 
+            pa = NULL;
+        }
+        // Separate test (if allocation of pa throws, el may be allocated.
+        // but no elements will be constructed.)
+        if(el) {
+            elements_array_allocator().deallocate(el, sz / 2);
+            el = NULL;
+        }
+        sz = INITIAL_SIZE;
+        ne = 0;
     }
 
 public:
     tagged_buffer() : my_size(INITIAL_SIZE), nelements(0) {
-        array = pointer_array_allocator_type().allocate(my_size);
-        for(size_t i = 0; i < my_size; ++i) array[i] = NULL;
-        lists = new list_array_type(INITIAL_SIZE/2, element_type(), Allocator());
-        set_up_free_list(&free_list, lists, INITIAL_SIZE/2);
+        internal_initialize_buffer();
     }
 
     ~tagged_buffer() {
-        if(array) {
-            pointer_array_allocator_type().deallocate(array, my_size); 
-        }
-        if(lists) {
-            delete lists;
-        }
+        internal_free_buffer(pointer_array, elements_array, my_size, nelements);
+    }
+
+    void reset() {
+        internal_free_buffer(pointer_array, elements_array, my_size, nelements);
+        internal_initialize_buffer();
     }
 
-    bool tagged_insert(TagType t, value_type v) {
+    bool tagged_insert(const TagType t, const value_type &v) {
         pointer_type p;
         if(tagged_find_ref(t, p)) {
-            *p = v;  // replace the value
+            p->~value_type();
+            (void) new(p) value_type(v);  // copy-construct into the space
             return false;
         }
         ++nelements;
         if(nelements*2 > my_size) grow_array();
-        internal_tagged_insert(array, my_size, t, v);
+        internal_tagged_insert(pointer_array, my_size, free_list, t, v);
         return true;
     }
 
     // returns reference to array element.v
-    bool tagged_find_ref(TagType t, pointer_type &v) {
+    bool tagged_find_ref(const TagType t, pointer_type &v) {
         size_t i = hash(t) & mask();
-        for(element_type* p = array[i]; p; p = p->next) {
-            if(p->t == t) {
-                v = &(p->v);
+        for(element_type* p = pointer_array[i]; p; p = (element_type *)(p->second.next)) {
+            if(p->second.t == t) {
+                v = reinterpret_cast<pointer_type>(&(p->first));
                 return true;
             }
         }
         return false;
     }
 
-    bool tagged_find( TagType t, value_type &v) {
+    bool tagged_find( const TagType t, value_type &v) {
         value_type *p;
         if(tagged_find_ref(t, p)) {
             v = *p;
@@ -180,15 +229,17 @@ public:
             return false;
     }
 
-    void tagged_delete(TagType t) {
+    void tagged_delete(const TagType t) {
         size_t h = hash(t) & mask();
         element_type* prev = NULL;
-        for(element_type* p = array[h]; p; prev = p, p = p->next) {
-            if(p->t == t) {
-                p->t = NO_TAG;
-                if(prev) prev->next = p->next;
-                else array[h] = p->next;
-                p->next = free_list;
+        for(element_type* p = pointer_array[h]; p; prev = p, p = (element_type *)(p->second.next)) {
+            if(p->second.t == t) {
+                value_type *vp = reinterpret_cast<value_type *>(&(p->first));
+                vp->~value_type();
+                p->second.t = NO_TAG;
+                if(prev) prev->second.next = p->second.next;
+                else pointer_array[h] = (element_type *)(p->second.next);
+                p->second.next = free_list;
                 free_list = p;
                 --nelements;
                 return;
@@ -196,17 +247,5 @@ public:
         }
         __TBB_ASSERT(false, "tag not found for delete");
     }
-
-    // search for v in the array; if found {set t, return true} else return false
-    // we use this in join_node_FE to find if a tag's items are all available.
-    bool find_value_tag( TagType &t, value_type v) {
-        for(size_t i= 0; i < my_size / 2; ++i) {  // remember the vector is half the size of the hash array
-            if( (*lists)[i].t != NO_TAG && (*lists)[i].v == v) {
-                t = (*lists)[i].t;
-                return true;
-            }
-        }
-        return false;
-    }
 };
 #endif // __TBB__flow_graph_tagged_buffer_impl_H
diff --git a/dependencies64/tbb/include/tbb/internal/_flow_graph_trace_impl.h b/dependencies64/tbb/include/tbb/internal/_flow_graph_trace_impl.h
new file mode 100644 (file)
index 0000000..43efc7c
--- /dev/null
@@ -0,0 +1,205 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef _FGT_GRAPH_TRACE_IMPL_H
+#define _FGT_GRAPH_TRACE_IMPL_H
+
+#include "../tbb_profiling.h"
+
+namespace tbb {
+    namespace internal {
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+
+static inline void fgt_internal_create_input_port( void *node, void *p, string_index name_index ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_INPUT_PORT, node, FLOW_NODE, name_index );
+}
+
+static inline void fgt_internal_create_output_port( void *node, void *p, string_index name_index ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, p, FLOW_OUTPUT_PORT, node, FLOW_NODE, name_index );
+}
+
+template < typename TypesTuple, typename PortsTuple, int N >
+struct fgt_internal_input_helper {
+    static void register_port( void *node, PortsTuple &ports ) {
+        fgt_internal_create_input_port( node, (void*)static_cast< tbb::flow::interface7::receiver< typename tbb::flow::tuple_element<N-1,TypesTuple>::type > * >(&(tbb::flow::get<N-1>(ports))),
+                                        static_cast<tbb::internal::string_index>(FLOW_INPUT_PORT_0 + N - 1) );
+        fgt_internal_input_helper<TypesTuple, PortsTuple, N-1>::register_port( node, ports );
+    } 
+};
+
+template < typename TypesTuple, typename PortsTuple >
+struct fgt_internal_input_helper<TypesTuple,PortsTuple,1> {
+    static void register_port( void *node, PortsTuple &ports ) {
+        fgt_internal_create_input_port( node, (void*)static_cast< tbb::flow::interface7::receiver< typename tbb::flow::tuple_element<0,TypesTuple>::type > * >(&(tbb::flow::get<0>(ports))),
+                                        FLOW_INPUT_PORT_0 );
+    } 
+};
+
+template < typename TypesTuple, typename PortsTuple, int N >
+struct fgt_internal_output_helper {
+    static void register_port( void *node, PortsTuple &ports ) {
+        fgt_internal_create_output_port( node, (void*)static_cast< tbb::flow::interface7::sender< typename tbb::flow::tuple_element<N-1,TypesTuple>::type > * >(&(tbb::flow::get<N-1>(ports))),
+                                         static_cast<tbb::internal::string_index>(FLOW_OUTPUT_PORT_0 + N - 1) ); 
+        fgt_internal_output_helper<TypesTuple, PortsTuple, N-1>::register_port( node, ports );
+    } 
+};
+
+template < typename TypesTuple, typename PortsTuple >
+struct fgt_internal_output_helper<TypesTuple,PortsTuple,1> {
+    static void register_port( void *node, PortsTuple &ports ) {
+        fgt_internal_create_output_port( node, (void*)static_cast< tbb::flow::interface7::sender< typename tbb::flow::tuple_element<0,TypesTuple>::type > * >(&(tbb::flow::get<0>(ports))),
+                                         FLOW_OUTPUT_PORT_0 ); 
+    } 
+};
+
+template< typename NodeType >
+void fgt_multioutput_node_desc( const NodeType *node, const char *desc ) {
+    void *addr =  (void *)( static_cast< tbb::flow::interface7::receiver< typename NodeType::input_type > * >(const_cast< NodeType *>(node)) ); 
+    itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); 
+}
+
+template< typename NodeType >
+static inline void fgt_node_desc( const NodeType *node, const char *desc ) {
+    void *addr =  (void *)( static_cast< tbb::flow::interface7::sender< typename NodeType::output_type > * >(const_cast< NodeType *>(node)) ); 
+    itt_metadata_str_add( ITT_DOMAIN_FLOW, addr, FLOW_NODE, FLOW_OBJECT_NAME, desc ); 
+}
+
+static inline void fgt_graph_desc( void *g, const char *desc ) {
+    itt_metadata_str_add( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, FLOW_OBJECT_NAME, desc ); 
+}
+
+static inline void fgt_body( void *node, void *body ) {
+    itt_relation_add( ITT_DOMAIN_FLOW, body, FLOW_BODY, __itt_relation_is_child_of, node, FLOW_NODE );
+}
+
+template< typename OutputTuple, int N, typename PortsTuple >
+static inline void fgt_multioutput_node( string_index t, void *g, void *input_port, PortsTuple &ports ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); 
+    fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); 
+    fgt_internal_output_helper<OutputTuple, PortsTuple, N>::register_port( input_port, ports ); 
+}
+
+template< typename OutputTuple, int N, typename PortsTuple >
+static inline void fgt_multioutput_node_with_body( string_index t, void *g, void *input_port, PortsTuple &ports, void *body ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, input_port, FLOW_NODE, g, FLOW_GRAPH, t ); 
+    fgt_internal_create_input_port( input_port, input_port, FLOW_INPUT_PORT_0 ); 
+    fgt_internal_output_helper<OutputTuple, PortsTuple, N>::register_port( input_port, ports ); 
+    fgt_body( input_port, body );
+}
+
+
+template< typename InputTuple, int N, typename PortsTuple >
+static inline void fgt_multiinput_node( string_index t, void *g, PortsTuple &ports, void *output_port) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); 
+    fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); 
+    fgt_internal_input_helper<InputTuple, PortsTuple, N>::register_port( output_port, ports ); 
+}
+
+static inline void fgt_node( string_index t, void *g, void *output_port ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); 
+    fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); 
+}
+
+static inline void fgt_node_with_body( string_index t, void *g, void *output_port, void *body ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, output_port, FLOW_NODE, g, FLOW_GRAPH, t ); 
+    fgt_internal_create_output_port( output_port, output_port, FLOW_OUTPUT_PORT_0 ); 
+    fgt_body( output_port, body );
+}
+
+
+static inline void fgt_node( string_index t, void *g, void *input_port, void *output_port ) {
+    fgt_node( t, g, output_port );
+    fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 );
+}
+
+static inline void fgt_node_with_body( string_index t, void *g, void *input_port, void *output_port, void *body ) {
+    fgt_node_with_body( t, g, output_port, body );
+    fgt_internal_create_input_port( output_port, input_port, FLOW_INPUT_PORT_0 ); 
+}
+
+
+static inline void  fgt_node( string_index t, void *g, void *input_port, void *decrement_port, void *output_port ) {
+    fgt_node( t, g, input_port, output_port );
+    fgt_internal_create_input_port( output_port, decrement_port, FLOW_INPUT_PORT_1 ); 
+}
+
+static inline void fgt_make_edge( void *output_port, void *input_port ) {
+    itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_predecessor_to, input_port, FLOW_INPUT_PORT);
+}
+
+static inline void fgt_remove_edge( void *output_port, void *input_port ) {
+    itt_relation_add( ITT_DOMAIN_FLOW, output_port, FLOW_OUTPUT_PORT, __itt_relation_is_sibling_of, input_port, FLOW_INPUT_PORT);
+}
+
+static inline void fgt_graph( void *g ) {
+    itt_make_task_group( ITT_DOMAIN_FLOW, g, FLOW_GRAPH, NULL, FLOW_NULL, FLOW_GRAPH ); 
+}
+
+static inline void fgt_begin_body( void *body ) {
+    itt_task_begin( ITT_DOMAIN_FLOW, body, FLOW_BODY, NULL, FLOW_NULL, FLOW_NULL );
+}
+
+static inline void fgt_end_body( void * ) {
+    itt_task_end( ITT_DOMAIN_FLOW );
+}
+
+#else // TBB_PREVIEW_FLOW_GRAPH_TRACE
+
+static inline void fgt_graph( void * /*g*/ ) { }
+
+template< typename NodeType >
+static inline void fgt_multioutput_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
+
+template< typename NodeType >
+static inline void fgt_node_desc( const NodeType * /*node*/, const char * /*desc*/ ) { }
+
+static inline void fgt_graph_desc( void * /*g*/, const char * /*desc*/ ) { }
+
+static inline void fgt_body( void * /*node*/, void * /*body*/ ) { }
+
+template< typename OutputTuple, int N, typename PortsTuple > 
+static inline void fgt_multioutput_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/ ) { }
+
+template< typename OutputTuple, int N, typename PortsTuple >
+static inline void fgt_multioutput_node_with_body( string_index /*t*/, void * /*g*/, void * /*input_port*/, PortsTuple & /*ports*/, void * /*body*/ ) { }
+
+template< typename InputTuple, int N, typename PortsTuple >
+static inline void fgt_multiinput_node( string_index /*t*/, void * /*g*/, PortsTuple & /*ports*/, void * /*output_port*/ ) { }
+
+static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*output_port*/ ) { } 
+static inline void fgt_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/ ) { } 
+static inline void  fgt_node( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*decrement_port*/, void * /*output_port*/ ) { }
+
+static inline void fgt_node_with_body( string_index /*t*/, void * /*g*/, void * /*output_port*/, void * /*body*/ ) { }
+static inline void fgt_node_with_body( string_index /*t*/, void * /*g*/, void * /*input_port*/, void * /*output_port*/, void * /*body*/ ) { }
+
+static inline void fgt_make_edge( void * /*output_port*/, void * /*input_port*/ ) { }
+static inline void fgt_remove_edge( void * /*output_port*/, void * /*input_port*/ ) { }
+
+static inline void fgt_begin_body( void * /*body*/ ) { }
+static inline void fgt_end_body( void *  /*body*/) { }
+
+#endif // TBB_PREVIEW_FLOW_GRAPH_TRACE
+
+    } // namespace internal
+} // namespace tbb
+
+#endif
index 335b04fb694205501bfdb7554d6823311a8ec74b..28a525a4de0f18b3d3ccd690fab0856aba0a72bf 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB__flow_graph_types_impl_H
@@ -33,6 +25,8 @@
 #error Do not #include this internal file directly; use public TBB headers instead.
 #endif
 
+// included in namespace tbb::flow::interface7
+
 namespace internal {
 // wrap each element of a tuple in a template, and make a tuple of the result.
 
@@ -41,118 +35,463 @@ namespace internal {
 
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<1, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type> >
             type;
     };
 
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<2, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>, 
-                PT<typename std::tuple_element<1,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type> >
             type;
     };
 
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<3, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type> >
             type;
     };
 
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<4, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type> >
             type;
     };
 
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<5, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type>,
-                PT<typename std::tuple_element<4,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<4,TypeTuple>::type> >
             type;
     };
 
+#if __TBB_VARIADIC_MAX >= 6
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<6, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type>,
-                PT<typename std::tuple_element<4,TypeTuple>::type>,
-                PT<typename std::tuple_element<5,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<4,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<5,TypeTuple>::type> >
             type;
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 7
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<7, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type>,
-                PT<typename std::tuple_element<4,TypeTuple>::type>,
-                PT<typename std::tuple_element<5,TypeTuple>::type>,
-                PT<typename std::tuple_element<6,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<4,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<5,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<6,TypeTuple>::type> >
             type;
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 8
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<8, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type>,
-                PT<typename std::tuple_element<4,TypeTuple>::type>,
-                PT<typename std::tuple_element<5,TypeTuple>::type>,
-                PT<typename std::tuple_element<6,TypeTuple>::type>,
-                PT<typename std::tuple_element<7,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<4,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<5,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<6,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<7,TypeTuple>::type> >
             type;
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 9
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<9, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type>,
-                PT<typename std::tuple_element<4,TypeTuple>::type>,
-                PT<typename std::tuple_element<5,TypeTuple>::type>,
-                PT<typename std::tuple_element<6,TypeTuple>::type>,
-                PT<typename std::tuple_element<7,TypeTuple>::type>,
-                PT<typename std::tuple_element<8,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<4,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<5,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<6,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<7,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<8,TypeTuple>::type> >
             type;
     };
+#endif
 
+#if __TBB_VARIADIC_MAX >= 10
     template<template<class> class PT, typename TypeTuple>
     struct wrap_tuple_elements<10, PT, TypeTuple> {
-        typedef typename std::tuple<
-                PT<typename std::tuple_element<0,TypeTuple>::type>,
-                PT<typename std::tuple_element<1,TypeTuple>::type>,
-                PT<typename std::tuple_element<2,TypeTuple>::type>,
-                PT<typename std::tuple_element<3,TypeTuple>::type>,
-                PT<typename std::tuple_element<4,TypeTuple>::type>,
-                PT<typename std::tuple_element<5,TypeTuple>::type>,
-                PT<typename std::tuple_element<6,TypeTuple>::type>,
-                PT<typename std::tuple_element<7,TypeTuple>::type>,
-                PT<typename std::tuple_element<8,TypeTuple>::type>,
-                PT<typename std::tuple_element<9,TypeTuple>::type> >
+        typedef typename tbb::flow::tuple<
+                PT<typename tbb::flow::tuple_element<0,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<1,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<2,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<3,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<4,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<5,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<6,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<7,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<8,TypeTuple>::type>,
+                PT<typename tbb::flow::tuple_element<9,TypeTuple>::type> >
             type;
     };
+#endif
+
+//! type mimicking std::pair but with trailing fill to ensure each element of an array
+//* will have the correct alignment
+    template<typename T1, typename T2, size_t REM>
+    struct type_plus_align {
+        char first[sizeof(T1)];
+        T2 second;
+        char fill1[REM];
+    };
+
+    template<typename T1, typename T2>
+    struct type_plus_align<T1,T2,0> {
+        char first[sizeof(T1)];
+        T2 second;
+    };
+
+    template<class U> struct alignment_of {
+        typedef struct { char t; U    padded; } test_alignment;
+        static const size_t value = sizeof(test_alignment) - sizeof(U);
+    };
+
+    // T1, T2 are actual types stored.  The space defined for T1 in the type returned
+    // is a char array of the correct size.  Type T2 should be trivially-constructible,
+    // T1 must be explicitly managed.
+    template<typename T1, typename T2>
+    struct aligned_pair {
+        static const size_t t1_align = alignment_of<T1>::value;
+        static const size_t t2_align = alignment_of<T2>::value;
+        typedef type_plus_align<T1, T2, 0 > just_pair;
+        static const size_t max_align = t1_align < t2_align ? t2_align : t1_align;
+        static const size_t extra_bytes = sizeof(just_pair) % max_align;
+        static const size_t remainder = extra_bytes ? max_align - extra_bytes : 0;
+    public:
+        typedef type_plus_align<T1,T2,remainder> type;
+    };  // aligned_pair
+
+// support for variant type
+// type we use when we're not storing a value
+struct default_constructed { };
+
+// type which contains another type, tests for what type is contained, and references to it.
+// internal::Wrapper<T>
+//     void CopyTo( void *newSpace) : builds a Wrapper<T> copy of itself in newSpace
+
+// struct to allow us to copy and test the type of objects
+struct WrapperBase {
+    virtual ~WrapperBase() {}
+    virtual void CopyTo(void* /*newSpace*/) const {  }
+};
+
+// Wrapper<T> contains a T, with the ability to test what T is.  The Wrapper<T> can be
+// constructed from a T, can be copy-constructed from another Wrapper<T>, and can be
+// examined via value(), but not modified.
+template<typename T>
+struct Wrapper: public WrapperBase {
+    typedef T value_type;
+    typedef T* pointer_type;
+private:
+    T value_space;
+public:
+    const value_type &value() const { return value_space; }
+
+private:
+    Wrapper();
+
+    // on exception will ensure the Wrapper will contain only a trivially-constructed object
+    struct _unwind_space {
+        pointer_type space;
+        _unwind_space(pointer_type p) : space(p) {}
+        ~_unwind_space() {
+            if(space) (void) new (space) Wrapper<default_constructed>(default_constructed());
+        }
+    };
+public:
+    explicit Wrapper( const T& other ) : value_space(other) { }
+    explicit Wrapper(const Wrapper& other) : value_space(other.value_space) { }
+
+    /*override*/void CopyTo(void* newSpace) const {
+        _unwind_space guard((pointer_type)newSpace);
+        (void) new(newSpace) Wrapper(value_space);
+        guard.space = NULL;
+    }
+    /*override*/~Wrapper() { }
+};
+
+// specialization for array objects
+template<typename T, size_t N>
+struct Wrapper<T[N]> : public WrapperBase {
+    typedef T value_type;
+    typedef T* pointer_type;
+    // space must be untyped.
+    typedef T ArrayType[N];
+private:
+    // The space is not of type T[N] because when copy-constructing, it would be
+    // default-initialized and then copied to in some fashion, resulting in two
+    // constructions and one destruction per element.  If the type is char[ ], we
+    // placement new into each element, resulting in one construction per element.
+    static const size_t space_size = sizeof(ArrayType) / sizeof(char);
+    char value_space[space_size];
+
+
+    // on exception will ensure the already-built objects will be destructed
+    // (the value_space is a char array, so it is already trivially-destructible.)
+    struct _unwind_class {
+        pointer_type space;
+        int    already_built;
+        _unwind_class(pointer_type p) : space(p), already_built(0) {}
+        ~_unwind_class() {
+            if(space) {
+                for(size_t i = already_built; i > 0 ; --i ) space[i-1].~value_type();
+                (void) new(space) Wrapper<default_constructed>(default_constructed());
+            }
+        }
+    };
+public:
+    const ArrayType &value() const {
+        char *vp = const_cast<char *>(value_space);
+        return reinterpret_cast<ArrayType &>(*vp);
+    }
+
+private:
+    Wrapper();
+public:
+    // have to explicitly construct because other decays to a const value_type*
+    explicit Wrapper(const ArrayType& other) {
+        _unwind_class guard((pointer_type)value_space);
+        pointer_type vp = reinterpret_cast<pointer_type>(&value_space);
+        for(size_t i = 0; i < N; ++i ) {
+            (void) new(vp++) value_type(other[i]);
+            ++(guard.already_built);
+        }
+        guard.space = NULL;
+    }
+    explicit Wrapper(const Wrapper& other) : WrapperBase() {
+        // we have to do the heavy lifting to copy contents
+        _unwind_class guard((pointer_type)value_space);
+        pointer_type dp = reinterpret_cast<pointer_type>(value_space);
+        pointer_type sp = reinterpret_cast<pointer_type>(const_cast<char *>(other.value_space));
+        for(size_t i = 0; i < N; ++i, ++dp, ++sp) {
+            (void) new(dp) value_type(*sp);
+            ++(guard.already_built);
+        }
+        guard.space = NULL;
+    }
+
+    /*override*/void CopyTo(void* newSpace) const {
+        (void) new(newSpace) Wrapper(*this);  // exceptions handled in copy constructor
+    }
+
+    /*override*/~Wrapper() {
+        // have to destroy explicitly in reverse order
+        pointer_type vp = reinterpret_cast<pointer_type>(&value_space);
+        for(size_t i = N; i > 0 ; --i ) vp[i-1].~value_type();
+    }
+};
+
+// given a tuple, return the type of the element that has the maximum alignment requirement.
+// Given a tuple and that type, return the number of elements of the object with the max
+// alignment requirement that is at least as big as the largest object in the tuple.
+
+template<bool, class T1, class T2> struct pick_one;
+template<class T1, class T2> struct pick_one<true , T1, T2> { typedef T1 type; };
+template<class T1, class T2> struct pick_one<false, T1, T2> { typedef T2 type; };
+
+template< template<class> class Selector, typename T1, typename T2 >
+struct pick_max {
+    typedef typename pick_one< (Selector<T1>::value > Selector<T2>::value), T1, T2 >::type type;
+};
+
+template<typename T> struct size_of { static const int value = sizeof(T); };
+
+template< size_t N, class Tuple, template<class> class Selector > struct pick_tuple_max {
+    typedef typename pick_tuple_max<N-1, Tuple, Selector>::type LeftMaxType;
+    typedef typename tbb::flow::tuple_element<N-1, Tuple>::type ThisType;
+    typedef typename pick_max<Selector, LeftMaxType, ThisType>::type type;
+};
+
+template< class Tuple, template<class> class Selector > struct pick_tuple_max<0, Tuple, Selector> {
+    typedef typename tbb::flow::tuple_element<0, Tuple>::type type;
+};
+
+// is the specified type included in a tuple?
+
+template<class U, class V> struct is_same_type      { static const bool value = false; };
+template<class W>          struct is_same_type<W,W> { static const bool value = true; };
+
+template<class Q, size_t N, class Tuple>
+struct is_element_of {
+    typedef typename tbb::flow::tuple_element<N-1, Tuple>::type T_i;
+    static const bool value = is_same_type<Q,T_i>::value || is_element_of<Q,N-1,Tuple>::value;
+};
+
+template<class Q, class Tuple>
+struct is_element_of<Q,0,Tuple> {
+    typedef typename tbb::flow::tuple_element<0, Tuple>::type T_i;
+    static const bool value = is_same_type<Q,T_i>::value;
+};
+
+// allow the construction of types that are listed tuple.  If a disallowed type
+// construction is written, a method involving this type is created.  The
+// type has no definition, so a syntax error is generated.
+template<typename T> struct ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple;
+
+template<typename T, bool BUILD_IT> struct do_if;
+template<typename T>
+struct do_if<T, true> {
+    static void construct(void *mySpace, const T& x) {
+        (void) new(mySpace) Wrapper<T>(x);
+    }
+};
+template<typename T>
+struct do_if<T, false> {
+    static void construct(void * /*mySpace*/, const T& x) {
+        // This method is instantiated when the type T does not match any of the
+        // element types in the Tuple in variant<Tuple>.
+        ERROR_Type_Not_allowed_In_Tagged_Msg_Not_Member_Of_Tuple<T>::bad_type(x);
+    }
+};
+
+// Tuple tells us the allowed types that variant can hold.  It determines the alignment of the space in
+// Wrapper, and how big Wrapper is.
+//
+// the object can only be tested for type, and a read-only reference can be fetched by cast_to<T>().
+
+using tbb::internal::punned_cast;
+struct tagged_null_type {};
+template<typename TagType, typename T0, typename T1=tagged_null_type, typename T2=tagged_null_type, typename T3=tagged_null_type, 
+                           typename T4=tagged_null_type, typename T5=tagged_null_type, typename T6=tagged_null_type,
+                           typename T7=tagged_null_type, typename T8=tagged_null_type, typename T9=tagged_null_type>
+class tagged_msg {
+    typedef tbb::flow::tuple<T0, T1, T2, T3, T4
+                  #if __TBB_VARIADIC_MAX >= 6
+                  , T5
+                  #endif
+                  #if __TBB_VARIADIC_MAX >= 7
+                  , T6
+                  #endif
+                  #if __TBB_VARIADIC_MAX >= 8
+                  , T7
+                  #endif
+                  #if __TBB_VARIADIC_MAX >= 9
+                  , T8
+                  #endif
+                  #if __TBB_VARIADIC_MAX >= 10
+                  , T9
+                  #endif
+                  > Tuple;   
+
+private:
+    class variant {
+        static const size_t N = tbb::flow::tuple_size<Tuple>::value;
+        typedef typename pick_tuple_max<N, Tuple, alignment_of>::type AlignType;
+        typedef typename pick_tuple_max<N, Tuple, size_of>::type MaxSizeType;
+        static const size_t MaxNBytes = (sizeof(Wrapper<MaxSizeType>)+sizeof(AlignType)-1);
+        static const size_t MaxNElements = MaxNBytes/sizeof(AlignType);
+        typedef typename tbb::aligned_space<AlignType, MaxNElements> SpaceType;
+        SpaceType my_space;
+        static const size_t MaxSize = sizeof(SpaceType);
+
+    public:
+        variant() { (void) new(&my_space) Wrapper<default_constructed>(default_constructed()); }
+
+        template<typename T>
+        variant( const T& x ) {
+            do_if<T, is_element_of<T, N, Tuple>::value>::construct(&my_space,x);
+        }
+
+        variant(const variant& other) {
+            const WrapperBase * h = punned_cast<const WrapperBase *>(&(other.my_space));
+            h->CopyTo(&my_space);
+        }
+
+        // assignment must destroy and re-create the Wrapper type, as there is no way
+        // to create a Wrapper-to-Wrapper assign even if we find they agree in type.
+        void operator=( const variant& rhs ) {
+            if(&rhs != this) {
+                WrapperBase *h = punned_cast<WrapperBase *>(&my_space);
+                h->~WrapperBase();
+                const WrapperBase *ch = punned_cast<const WrapperBase *>(&(rhs.my_space));
+                ch->CopyTo(&my_space);
+            }
+        }
+
+        template<typename U>
+        const U& variant_cast_to() const {
+            const Wrapper<U> *h = dynamic_cast<const Wrapper<U>*>(punned_cast<const WrapperBase *>(&my_space));
+            if(!h) {
+                tbb::internal::throw_exception(tbb::internal::eid_bad_tagged_msg_cast);
+            }
+            return h->value();
+        }
+        template<typename U>
+        bool variant_is_a() const { return dynamic_cast<const Wrapper<U>*>(punned_cast<const WrapperBase *>(&my_space)) != NULL; }
+
+        bool variant_is_default_constructed() const {return variant_is_a<default_constructed>();}
+
+        ~variant() {
+            WrapperBase *h = punned_cast<WrapperBase *>(&my_space);
+            h->~WrapperBase();
+        }
+    }; //class variant
+
+    TagType my_tag;
+    variant my_msg;
+
+public:
+    tagged_msg(): my_tag(TagType(~0)), my_msg(){} 
+
+    template<typename T, typename R>
+    tagged_msg(T const &index, R const &value) : my_tag(index), my_msg(value) {}
+    
+    #if __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN
+    template<typename T, typename R, size_t N>
+    tagged_msg(T const &index,  R (&value)[N]) : my_tag(index), my_msg(value) {}
+    #endif
+
+    void set_tag(TagType const &index) {my_tag = index;}
+    TagType tag() const {return my_tag;}
+
+    template<typename V>
+    const V& cast_to() const {return my_msg.template variant_cast_to<V>();}
+
+    template<typename V>
+    bool is_a() const {return my_msg.template variant_is_a<V>();}
+
+    bool is_default_constructed() const {return my_msg.variant_is_default_constructed();}
+}; //class tagged_msg
+
+// template to simplify cast and test for tagged_msg in template contexts
+template<typename T, typename V>
+const T& cast_to(V const &v) { return v.template cast_to<T>(); }
+
+template<typename T, typename V>
+bool is_a(V const &v) { return v.template is_a<T>(); }
 
 }  // namespace internal
+
 #endif  /* __TBB__flow_graph_types_impl_H */
diff --git a/dependencies64/tbb/include/tbb/internal/_mutex_padding.h b/dependencies64/tbb/include/tbb/internal/_mutex_padding.h
new file mode 100644 (file)
index 0000000..ae07599
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_mutex_padding_H
+#define __TBB_mutex_padding_H
+
+// wrapper for padding mutexes to be alone on a cache line, without requiring they be allocated
+// from a pool.  Because we allow them to be defined anywhere they must be two cache lines in size.
+
+
+namespace tbb {
+namespace interface7 {
+namespace internal {
+
+static const size_t cache_line_size = 64;
+
+// Pad a mutex to occupy a number of full cache lines sufficient to avoid false sharing
+// with other data; space overhead is up to 2*cache_line_size-1.
+template<typename Mutex, bool is_rw> class padded_mutex;
+
+template<typename Mutex>
+class padded_mutex<Mutex,false> : tbb::internal::mutex_copy_deprecated_and_disabled {
+    typedef long pad_type;
+    pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)];
+
+    Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);}
+
+public:
+    static const bool is_rw_mutex = Mutex::is_rw_mutex;
+    static const bool is_recursive_mutex = Mutex::is_recursive_mutex;
+    static const bool is_fair_mutex = Mutex::is_fair_mutex;
+
+    padded_mutex() { new(impl()) Mutex(); }
+    ~padded_mutex() { impl()->~Mutex(); }
+
+    //! Represents acquisition of a mutex.
+    class scoped_lock :  tbb::internal::no_copy {
+        typename Mutex::scoped_lock my_scoped_lock;
+    public:
+        scoped_lock() : my_scoped_lock() {}
+        scoped_lock( padded_mutex& m ) : my_scoped_lock(*m.impl()) { }
+        ~scoped_lock() {  }
+
+        void acquire( padded_mutex& m ) { my_scoped_lock.acquire(*m.impl()); }
+        bool try_acquire( padded_mutex& m ) { return my_scoped_lock.try_acquire(*m.impl()); }
+        void release() { my_scoped_lock.release(); }
+    };
+};
+
+template<typename Mutex>
+class padded_mutex<Mutex,true> : tbb::internal::mutex_copy_deprecated_and_disabled {
+    typedef long pad_type;
+    pad_type my_pad[((sizeof(Mutex)+cache_line_size-1)/cache_line_size+1)*cache_line_size/sizeof(pad_type)];
+
+    Mutex *impl() { return (Mutex *)((uintptr_t(this)|(cache_line_size-1))+1);}
+
+public:
+    static const bool is_rw_mutex = Mutex::is_rw_mutex;
+    static const bool is_recursive_mutex = Mutex::is_recursive_mutex;
+    static const bool is_fair_mutex = Mutex::is_fair_mutex;
+
+    padded_mutex() { new(impl()) Mutex(); }
+    ~padded_mutex() { impl()->~Mutex(); }
+
+    //! Represents acquisition of a mutex.
+    class scoped_lock :  tbb::internal::no_copy {
+        typename Mutex::scoped_lock my_scoped_lock;
+    public:
+        scoped_lock() : my_scoped_lock() {}
+        scoped_lock( padded_mutex& m, bool write = true ) : my_scoped_lock(*m.impl(),write) { }
+        ~scoped_lock() {  }
+
+        void acquire( padded_mutex& m, bool write = true ) { my_scoped_lock.acquire(*m.impl(),write); }
+        bool try_acquire( padded_mutex& m, bool write = true ) { return my_scoped_lock.try_acquire(*m.impl(),write); }
+        bool upgrade_to_writer() { return my_scoped_lock.upgrade_to_writer(); }
+        bool downgrade_to_reader() { return my_scoped_lock.downgrade_to_reader(); }
+        void release() { my_scoped_lock.release(); }
+    };
+};
+
+} // namespace internal
+} // namespace interface7
+} // namespace tbb
+
+#endif /* __TBB_mutex_padding_H */
diff --git a/dependencies64/tbb/include/tbb/internal/_range_iterator.h b/dependencies64/tbb/include/tbb/internal/_range_iterator.h
new file mode 100644 (file)
index 0000000..0622c4f
--- /dev/null
@@ -0,0 +1,70 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_range_iterator_H
+#define __TBB_range_iterator_H
+
+#include "../tbb_stddef.h"
+
+#if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT
+    #include <iterator>
+#endif
+
+namespace tbb {
+    // iterators to first and last elements of container
+    namespace internal {
+
+#if __TBB_CPP11_STD_BEGIN_END_PRESENT && __TBB_CPP11_AUTO_PRESENT && __TBB_CPP11_DECLTYPE_PRESENT
+        using std::begin;
+        using std::end;
+        template<typename Container>
+        auto first(Container& c)-> decltype(begin(c))  {return begin(c);}
+
+        template<typename Container>
+        auto first(const Container& c)-> decltype(begin(c))  {return begin(c);}
+
+        template<typename Container>
+        auto last(Container& c)-> decltype(begin(c))  {return end(c);}
+
+        template<typename Container>
+        auto last(const Container& c)-> decltype(begin(c)) {return end(c);}
+#else
+        template<typename Container>
+        typename Container::iterator first(Container& c) {return c.begin();}
+
+        template<typename Container>
+        typename Container::const_iterator first(const Container& c) {return c.begin();}
+
+        template<typename Container>
+        typename Container::iterator last(Container& c) {return c.end();}
+
+        template<typename Container>
+        typename Container::const_iterator last(const Container& c) {return c.end();}
+#endif
+
+        template<typename T, size_t size>
+        T* first(T (&arr) [size]) {return arr;}
+
+        template<typename T, size_t size>
+        T* last(T (&arr) [size]) {return arr + size;}
+    } //namespace internal
+}  //namespace tbb
+
+#endif // __TBB_range_iterator_H
diff --git a/dependencies64/tbb/include/tbb/internal/_tbb_strings.h b/dependencies64/tbb/include/tbb/internal/_tbb_strings.h
new file mode 100644 (file)
index 0000000..ccffe1d
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+TBB_STRING_RESOURCE(FLOW_BROADCAST_NODE, "broadcast_node")
+TBB_STRING_RESOURCE(FLOW_BUFFER_NODE, "buffer_node")
+TBB_STRING_RESOURCE(FLOW_CONTINUE_NODE, "continue_node")
+TBB_STRING_RESOURCE(FLOW_FUNCTION_NODE, "function_node")
+TBB_STRING_RESOURCE(FLOW_JOIN_NODE_QUEUEING, "join_node (queueing)")
+TBB_STRING_RESOURCE(FLOW_JOIN_NODE_RESERVING, "join_node (reserving)")
+TBB_STRING_RESOURCE(FLOW_JOIN_NODE_TAG_MATCHING, "join_node (tag_matching)")
+TBB_STRING_RESOURCE(FLOW_LIMITER_NODE, "limiter_node")
+TBB_STRING_RESOURCE(FLOW_MULTIFUNCTION_NODE, "multifunction_node")
+TBB_STRING_RESOURCE(FLOW_OR_NODE, "or_node") //no longer in use, kept for backward compatibilty
+TBB_STRING_RESOURCE(FLOW_OVERWRITE_NODE, "overwrite_node")
+TBB_STRING_RESOURCE(FLOW_PRIORITY_QUEUE_NODE, "priority_queue_node")
+TBB_STRING_RESOURCE(FLOW_QUEUE_NODE, "queue_node")
+TBB_STRING_RESOURCE(FLOW_SEQUENCER_NODE, "sequencer_node")
+TBB_STRING_RESOURCE(FLOW_SOURCE_NODE, "source_node")
+TBB_STRING_RESOURCE(FLOW_SPLIT_NODE, "split_node")
+TBB_STRING_RESOURCE(FLOW_WRITE_ONCE_NODE, "write_once_node")
+TBB_STRING_RESOURCE(FLOW_BODY, "body")
+TBB_STRING_RESOURCE(FLOW_GRAPH, "graph")
+TBB_STRING_RESOURCE(FLOW_NODE, "node")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT, "input_port")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_0, "input_port_0")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_1, "input_port_1")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_2, "input_port_2")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_3, "input_port_3")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_4, "input_port_4")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_5, "input_port_5")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_6, "input_port_6")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_7, "input_port_7")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_8, "input_port_8")
+TBB_STRING_RESOURCE(FLOW_INPUT_PORT_9, "input_port_9")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT, "output_port")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_0, "output_port_0")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_1, "output_port_1")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_2, "output_port_2")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_3, "output_port_3")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_4, "output_port_4")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_5, "output_port_5")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_6, "output_port_6")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_7, "output_port_7")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_8, "output_port_8")
+TBB_STRING_RESOURCE(FLOW_OUTPUT_PORT_9, "output_port_9")
+TBB_STRING_RESOURCE(FLOW_OBJECT_NAME, "object_name")
+TBB_STRING_RESOURCE(FLOW_NULL, "null")
+TBB_STRING_RESOURCE(FLOW_INDEXER_NODE, "indexer_node")
index bda75c77b6cf92416c3ab1a019978288946b4cc4..551dc2b0bf80e94f55875d13b6a8bf89e0051479 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
 
-    This file is part of Threading Building Blocks.
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
 
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tbb_windef_H
@@ -32,8 +24,8 @@
 
 // Check that the target Windows version has all API calls requried for TBB.
 // Do not increase the version in condition beyond 0x0500 without prior discussion!
-#if defined(_WIN32_WINNT) && _WIN32_WINNT<0x0400
-#error TBB is unable to run on old Windows versions; _WIN32_WINNT must be 0x0400 or greater.
+#if defined(_WIN32_WINNT) && _WIN32_WINNT<0x0501
+#error TBB is unable to run on old Windows versions; _WIN32_WINNT must be 0x0501 or greater.
 #endif
 
 #if !defined(_MT)
@@ -62,7 +54,7 @@ namespace std {
 #    endif
 #endif
 
-#if __TBB_BUILD && !defined(__TBB_NO_IMPLICIT_LINKAGE)
+#if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBB_NO_IMPLICIT_LINKAGE)
 #define __TBB_NO_IMPLICIT_LINKAGE 1
 #endif
 
diff --git a/dependencies64/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h b/dependencies64/tbb/include/tbb/internal/_x86_eliding_mutex_impl.h
new file mode 100644 (file)
index 0000000..d73877a
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB__x86_eliding_mutex_impl_H
+#define __TBB__x86_eliding_mutex_impl_H
+
+#ifndef __TBB_spin_mutex_H
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#if ( __TBB_x86_32 || __TBB_x86_64 )
+
+namespace tbb {
+namespace interface7 {
+namespace internal {
+
+template<typename Mutex, bool is_rw>
+class padded_mutex;
+
+//! An eliding lock that occupies a single byte.
+/** A x86_eliding_mutex is an HLE-enabled spin mutex. It is recommended to
+    put the mutex on a cache line that is not shared by the data it protects.
+    It should be used for locking short critical sections where the lock is
+    contended but the data it protects are not.  If zero-initialized, the
+    mutex is considered unheld.
+    @ingroup synchronization */
+class x86_eliding_mutex : tbb::internal::mutex_copy_deprecated_and_disabled {
+    //! 0 if lock is released, 1 if lock is acquired.
+    __TBB_atomic_flag flag;
+
+    friend class padded_mutex<x86_eliding_mutex, false>;
+
+public:
+    //! Construct unacquired lock.
+    /** Equivalent to zero-initialization of *this. */
+    x86_eliding_mutex() : flag(0) {}
+
+// bug in gcc 3.x.x causes syntax error in spite of the friend declaration above.
+// Make the scoped_lock public in that case.
+#if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000
+#else
+    // by default we will not provide the scoped_lock interface.  The user
+    // should use the padded version of the mutex.  scoped_lock is used in
+    // padded_mutex template.
+private:
+#endif
+    // scoped_lock in padded_mutex<> is the interface to use.
+    //! Represents acquisition of a mutex.
+    class scoped_lock : tbb::internal::no_copy {
+    private:
+        //! Points to currently held mutex, or NULL if no lock is held.
+        x86_eliding_mutex* my_mutex;
+
+    public:
+        //! Construct without acquiring a mutex.
+        scoped_lock() : my_mutex(NULL) {}
+
+        //! Construct and acquire lock on a mutex.
+        scoped_lock( x86_eliding_mutex& m ) : my_mutex(NULL) { acquire(m); }
+
+        //! Acquire lock.
+        void acquire( x86_eliding_mutex& m ) {
+            __TBB_ASSERT( !my_mutex, "already holding a lock" );
+
+            my_mutex=&m;
+            my_mutex->lock();
+        }
+
+        //! Try acquiring lock (non-blocking)
+        /** Return true if lock acquired; false otherwise. */
+        bool try_acquire( x86_eliding_mutex& m ) {
+            __TBB_ASSERT( !my_mutex, "already holding a lock" );
+
+            bool result = m.try_lock();
+            if( result ) {
+                my_mutex = &m;
+            }
+            return result;
+        }
+
+        //! Release lock
+        void release() {
+            __TBB_ASSERT( my_mutex, "release on scoped_lock that is not holding a lock" );
+
+            my_mutex->unlock();
+            my_mutex = NULL;
+        }
+
+        //! Destroy lock.  If holding a lock, releases the lock first.
+        ~scoped_lock() {
+            if( my_mutex ) {
+                release();
+            }
+        }
+    };
+#if __TBB_USE_X86_ELIDING_MUTEX || __TBB_GCC_VERSION < 40000
+#else
+public:
+#endif  /* __TBB_USE_X86_ELIDING_MUTEX */
+
+    // Mutex traits
+    static const bool is_rw_mutex = false;
+    static const bool is_recursive_mutex = false;
+    static const bool is_fair_mutex = false;
+
+    // ISO C++0x compatibility methods
+
+    //! Acquire lock
+    void lock() {
+        __TBB_LockByteElided(flag);
+    }
+
+    //! Try acquiring lock (non-blocking)
+    /** Return true if lock acquired; false otherwise. */
+    bool try_lock() {
+        return __TBB_TryLockByteElided(flag);
+    }
+
+    //! Release lock
+    void unlock() {
+        __TBB_UnlockByteElided( flag );
+    }
+}; // end of x86_eliding_mutex
+
+} // namespace internal
+} // namespace interface7
+} // namespace tbb
+
+#endif /* ( __TBB_x86_32 || __TBB_x86_64 ) */
+
+#endif /* __TBB__x86_eliding_mutex_impl_H */
diff --git a/dependencies64/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h b/dependencies64/tbb/include/tbb/internal/_x86_rtm_rw_mutex_impl.h
new file mode 100644 (file)
index 0000000..9fb8c82
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB__x86_rtm_rw_mutex_impl_H
+#define __TBB__x86_rtm_rw_mutex_impl_H
+
+#ifndef __TBB_spin_rw_mutex_H
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#if __TBB_TSX_AVAILABLE
+
+#include "../tbb_stddef.h"
+#include "../tbb_machine.h"
+#include "../tbb_profiling.h"
+#include "../spin_rw_mutex.h"
+
+namespace tbb {
+namespace interface8 {
+namespace internal {
+
+enum RTM_type {
+    RTM_not_in_mutex,
+    RTM_transacting_reader,
+    RTM_transacting_writer,
+    RTM_real_reader,
+    RTM_real_writer
+};
+
+static const unsigned long speculation_granularity = 64;
+
+//! Fast, unfair, spinning speculation-enabled reader-writer lock with backoff and
+//  writer-preference
+/** @ingroup synchronization */
+class x86_rtm_rw_mutex: private spin_rw_mutex {
+#if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000
+// bug in gcc 3.x.x causes syntax error in spite of the friend declaration below.
+// Make the scoped_lock public in that case.
+public:
+#else
+private:
+#endif
+    friend class interface7::internal::padded_mutex<x86_rtm_rw_mutex,true>;
+    class scoped_lock;   // should be private 
+    friend class scoped_lock;
+private:
+    //! @cond INTERNAL
+
+    //! Internal construct unacquired mutex.
+    void __TBB_EXPORTED_METHOD internal_construct();
+
+    //! Internal acquire write lock.
+    // only_speculate == true if we're doing a try_lock, else false.
+    void __TBB_EXPORTED_METHOD internal_acquire_writer(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false);
+
+    //! Internal acquire read lock.
+    // only_speculate == true if we're doing a try_lock, else false.
+    void __TBB_EXPORTED_METHOD internal_acquire_reader(x86_rtm_rw_mutex::scoped_lock&, bool only_speculate=false);
+
+    //! Internal upgrade reader to become a writer.
+    bool __TBB_EXPORTED_METHOD internal_upgrade( x86_rtm_rw_mutex::scoped_lock& );
+
+    //! Out of line code for downgrading a writer to a reader.
+    bool __TBB_EXPORTED_METHOD internal_downgrade( x86_rtm_rw_mutex::scoped_lock& );
+
+    //! Internal try_acquire write lock.
+    bool __TBB_EXPORTED_METHOD internal_try_acquire_writer( x86_rtm_rw_mutex::scoped_lock& );
+
+    //! Internal release lock.
+    void __TBB_EXPORTED_METHOD internal_release( x86_rtm_rw_mutex::scoped_lock& );
+
+    static x86_rtm_rw_mutex* internal_get_mutex( const spin_rw_mutex::scoped_lock& lock )
+    {
+        return static_cast<x86_rtm_rw_mutex*>( lock.internal_get_mutex() );
+    }
+    static void internal_set_mutex( spin_rw_mutex::scoped_lock& lock, spin_rw_mutex* mtx )
+    {
+        lock.internal_set_mutex( mtx );
+    }
+    //! @endcond
+public:
+    //! Construct unacquired mutex.
+    x86_rtm_rw_mutex() {
+        w_flag = false;
+#if TBB_USE_THREADING_TOOLS
+        internal_construct();
+#endif
+    }
+
+#if TBB_USE_ASSERT
+    //! Empty destructor.
+    ~x86_rtm_rw_mutex() {}
+#endif /* TBB_USE_ASSERT */
+
+    // Mutex traits
+    static const bool is_rw_mutex = true;
+    static const bool is_recursive_mutex = false;
+    static const bool is_fair_mutex = false;
+
+#if __TBB_USE_X86_RTM_RW_MUTEX || __TBB_GCC_VERSION < 40000
+#else
+    // by default we will not provide the scoped_lock interface.  The user
+    // should use the padded version of the mutex.  scoped_lock is used in
+    // padded_mutex template.
+private:
+#endif
+    //! The scoped locking pattern
+    /** It helps to avoid the common problem of forgetting to release lock.
+        It also nicely provides the "node" for queuing locks. */
+    // Speculation-enabled scoped lock for spin_rw_mutex
+    // The idea is to be able to reuse the acquire/release methods of spin_rw_mutex
+    // and its scoped lock wherever possible.  The only way to use a speculative lock is to use
+    // a scoped_lock. (because transaction_state must be local)
+
+    class scoped_lock : tbb::internal::no_copy {
+        friend class x86_rtm_rw_mutex;
+        spin_rw_mutex::scoped_lock my_scoped_lock;
+
+        RTM_type transaction_state;
+
+    public:
+        //! Construct lock that has not acquired a mutex.
+        /** Equivalent to zero-initialization of *this. */
+        scoped_lock() : my_scoped_lock(), transaction_state(RTM_not_in_mutex) {
+        }
+
+        //! Acquire lock on given mutex.
+        scoped_lock( x86_rtm_rw_mutex& m, bool write = true ) : my_scoped_lock(),
+            transaction_state(RTM_not_in_mutex) {
+            acquire(m, write);
+        }
+
+        //! Release lock (if lock is held).
+        ~scoped_lock() {
+            if(transaction_state != RTM_not_in_mutex) release();
+        }
+
+        //! Acquire lock on given mutex.
+        void acquire( x86_rtm_rw_mutex& m, bool write = true ) {
+            if( write ) m.internal_acquire_writer(*this);
+            else        m.internal_acquire_reader(*this);
+        }
+
+        //! Release lock
+        void release() {
+            x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock);
+            __TBB_ASSERT( mutex, "lock is not acquired" );
+            __TBB_ASSERT( transaction_state!=RTM_not_in_mutex, "lock is not acquired" );
+            return mutex->internal_release(*this);
+        }
+
+        //! Upgrade reader to become a writer.
+        /** Returns whether the upgrade happened without releasing and re-acquiring the lock */
+        bool upgrade_to_writer() {
+            x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock);
+            __TBB_ASSERT( mutex, "lock is not acquired" );
+            __TBB_ASSERT( transaction_state==RTM_transacting_reader || transaction_state==RTM_real_reader, "Invalid state for upgrade" );
+            return mutex->internal_upgrade(*this);
+        }
+
+        //! Downgrade writer to become a reader.
+        /** Returns whether the downgrade happened without releasing and re-acquiring the lock */
+        bool downgrade_to_reader() {
+            x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock);
+            __TBB_ASSERT( mutex, "lock is not acquired" );
+            __TBB_ASSERT( transaction_state==RTM_transacting_writer || transaction_state==RTM_real_writer, "Invalid state for downgrade" );
+            return mutex->internal_downgrade(*this);
+        }
+
+        //! Attempt to acquire mutex.
+        /** returns true if successful.  */
+        bool try_acquire( x86_rtm_rw_mutex& m, bool write = true ) {
+#if TBB_USE_ASSERT
+            x86_rtm_rw_mutex* mutex = x86_rtm_rw_mutex::internal_get_mutex(my_scoped_lock);
+            __TBB_ASSERT( !mutex, "lock is already acquired" );
+#endif
+            // have to assign m to our mutex.
+            // cannot set the mutex, because try_acquire in spin_rw_mutex depends on it being NULL.
+            if(write) return m.internal_try_acquire_writer(*this);
+            // speculatively acquire the lock.  If this fails, do try_acquire on the spin_rw_mutex.
+            m.internal_acquire_reader(*this, /*only_speculate=*/true);
+            if(transaction_state == RTM_transacting_reader) return true;
+            if( my_scoped_lock.try_acquire(m, false)) {
+                transaction_state = RTM_real_reader;
+                return true;
+            }
+            return false;
+        }
+
+        };  // class x86_rtm_rw_mutex::scoped_lock
+
+    // ISO C++0x compatibility methods not provided because we cannot maintain
+    // state about whether a thread is in a transaction.
+
+private:
+    char pad[speculation_granularity-sizeof(spin_rw_mutex)]; // padding
+
+    // If true, writer holds the spin_rw_mutex.
+    tbb::atomic<bool> w_flag;  // want this on a separate cache line
+
+};  // x86_rtm_rw_mutex
+
+}  // namespace internal
+}  // namespace interface8
+}  // namespace tbb
+
+#endif  /* __TBB_TSX_AVAILABLE */
+#endif /* __TBB__x86_rtm_rw_mutex_impl_H */
diff --git a/dependencies64/tbb/include/tbb/machine/gcc_armv7.h b/dependencies64/tbb/include/tbb/machine/gcc_armv7.h
new file mode 100644 (file)
index 0000000..83f5c55
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+/*
+    Platform isolation layer for the ARMv7-a architecture.
+*/
+
+#ifndef __TBB_machine_H
+#error Do not include this file directly; include tbb_machine.h instead
+#endif
+
+//TODO: is ARMv7 is the only version ever to support?
+#if !(__ARM_ARCH_7A__)
+#error compilation requires an ARMv7-a architecture.
+#endif
+
+#include <sys/param.h>
+#include <unistd.h>
+
+#define __TBB_WORDSIZE 4
+
+// Traditionally ARM is little-endian.
+// Note that, since only the layout of aligned 32-bit words is of interest,
+// any apparent PDP-endianness of 32-bit words at half-word alignment or
+// any little-endian ordering of big-endian 32-bit words in 64-bit quantities
+// may be disregarded for this setting.
+#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
+#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
+#elif defined(__BYTE_ORDER__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
+#else
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT
+#endif
+
+
+#define __TBB_compiler_fence()    __asm__ __volatile__("": : :"memory")
+#define __TBB_full_memory_fence() __asm__ __volatile__("dmb ish": : :"memory")
+#define __TBB_control_consistency_helper() __TBB_full_memory_fence()
+#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence()
+#define __TBB_release_consistency_helper() __TBB_full_memory_fence()
+
+//--------------------------------------------------
+// Compare and swap
+//--------------------------------------------------
+
+/**
+ * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr
+ * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand
+ * @param value value to assign *ptr to if *ptr==comparand
+ * @param comparand value to compare with *ptr
+ * @return value originally in memory at ptr, regardless of success
+*/
+static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand )
+{
+    int32_t oldval, res;
+
+    __TBB_full_memory_fence();
+
+    do {
+    __asm__ __volatile__(
+        "ldrex      %1, [%3]\n"
+        "mov        %0, #0\n"
+        "cmp        %1, %4\n"
+        "it         eq\n"
+        "strexeq    %0, %5, [%3]\n"
+        : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int32_t*)ptr)
+        : "r" ((int32_t *)ptr), "Ir" (comparand), "r" (value)
+        : "cc");
+    } while (res);
+
+    __TBB_full_memory_fence();
+
+    return oldval;
+}
+
+/**
+ * Atomic CAS for 64 bit values, if *ptr==comparand, then *ptr=value, returns *ptr
+ * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand
+ * @param value value to assign *ptr to if *ptr==comparand
+ * @param comparand value to compare with *ptr
+ * @return value originally in memory at ptr, regardless of success
+ */
+static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, int64_t comparand )
+{
+    int64_t oldval;
+    int32_t res;
+
+    __TBB_full_memory_fence();
+
+    do {
+        __asm__ __volatile__(
+            "mov        %0, #0\n"
+            "ldrexd     %1, %H1, [%3]\n"
+            "cmp        %1, %4\n"
+            "it         eq\n"
+            "cmpeq      %H1, %H4\n"
+            "it         eq\n"
+            "strexdeq   %0, %5, %H5, [%3]"
+        : "=&r" (res), "=&r" (oldval), "+Qo" (*(volatile int64_t*)ptr)
+        : "r" ((int64_t *)ptr), "r" (comparand), "r" (value)
+        : "cc");
+    } while (res);
+
+    __TBB_full_memory_fence();
+
+    return oldval;
+}
+
+static inline int32_t __TBB_machine_fetchadd4(volatile void* ptr, int32_t addend)
+{
+    unsigned long tmp;
+    int32_t result, tmp2;
+
+    __TBB_full_memory_fence();
+
+    __asm__ __volatile__(
+"1:     ldrex   %0, [%4]\n"
+"       add     %3, %0, %5\n"
+"       strex   %1, %3, [%4]\n"
+"       cmp     %1, #0\n"
+"       bne     1b\n"
+    : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int32_t*)ptr), "=&r"(tmp2)
+    : "r" ((int32_t *)ptr), "Ir" (addend)
+    : "cc");
+
+    __TBB_full_memory_fence();
+
+    return result;
+}
+
+static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend)
+{
+    unsigned long tmp;
+    int64_t result, tmp2;
+
+    __TBB_full_memory_fence();
+
+    __asm__ __volatile__(
+"1:     ldrexd  %0, %H0, [%4]\n"
+"       adds    %3, %0, %5\n"
+"       adc     %H3, %H0, %H5\n"
+"       strexd  %1, %3, %H3, [%4]\n"
+"       cmp     %1, #0\n"
+"       bne     1b"
+    : "=&r" (result), "=&r" (tmp), "+Qo" (*(volatile int64_t*)ptr), "=&r"(tmp2)
+    : "r" ((int64_t *)ptr), "r" (addend)
+    : "cc");
+
+
+    __TBB_full_memory_fence();
+
+    return result;
+}
+
+inline void __TBB_machine_pause (int32_t delay )
+{
+    while(delay>0)
+    {
+       __TBB_compiler_fence();
+        delay--;
+    }
+}
+
+namespace tbb {
+namespace internal {
+    template <typename T, size_t S>
+    struct machine_load_store_relaxed {
+        static inline T load ( const volatile T& location ) {
+            const T value = location;
+
+            /*
+            * An extra memory barrier is required for errata #761319
+            * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a
+            */
+            __TBB_acquire_consistency_helper();
+            return value;
+        }
+
+        static inline void store ( volatile T& location, T value ) {
+            location = value;
+        }
+    };
+}} // namespaces internal, tbb
+
+// Machine specific atomic operations
+
+#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
+#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+
+// Use generics for some things
+#define __TBB_USE_GENERIC_PART_WORD_CAS                         1
+#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD                   1
+#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE                 1
+#define __TBB_USE_GENERIC_FETCH_STORE                           1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_DWORD_LOAD_STORE                      1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE     1
index 0192fde9103ab23ef1c46ff002df54321908e2c4..be80ed47fc534c101e625528280ed07cc51c979b 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_generic_H)
 #include <stdint.h>
 #include <unistd.h>
 
-#define __TBB_WORDSIZE      __SIZEOF_INT__
+#define __TBB_WORDSIZE      __SIZEOF_POINTER__
+
+#if __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN
+    #define __TBB_64BIT_ATOMICS 0
+#endif
+
+/** FPU control setting not available for non-Intel architectures on Android **/
+#if __ANDROID__ && __TBB_generic_arch 
+    #define __TBB_CPU_CTL_ENV_PRESENT 0
+#endif
 
-// For some reason straight mapping does not work on mingw
-#if __BYTE_ORDER__==__ORDER_BIG_ENDIAN__
-    #define __TBB_BIG_ENDIAN    0
-#elif __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__
-    #define __TBB_BIG_ENDIAN    1
+// __BYTE_ORDER__ is used in accordance with http://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html,
+// but __BIG_ENDIAN__ or __LITTLE_ENDIAN__ may be more commonly found instead.
+#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
+#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
+#elif defined(__BYTE_ORDER__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
 #else
-#error Unsupported endianness
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT
 #endif
 
 /** As this generic implementation has absolutely no information about underlying
 inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) {                    \
     return __sync_val_compare_and_swap(reinterpret_cast<volatile T *>(ptr),comparand,value);      \
 }                                                                                                 \
+                                                                                                  \
+inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) {                               \
+    return __sync_fetch_and_add(reinterpret_cast<volatile T *>(ptr),value);                       \
+}                                                                                                 \
 
 __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t)
 __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t)
@@ -68,7 +76,56 @@ __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t)
 
 #undef __TBB_MACHINE_DEFINE_ATOMICS
 
-#define __TBB_USE_GENERIC_FETCH_ADD                 1
-#define __TBB_USE_GENERIC_FETCH_STORE               1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
+namespace tbb{ namespace internal { namespace gcc_builtins {
+    inline int clz(unsigned int x){ return __builtin_clz(x);};
+    inline int clz(unsigned long int x){ return __builtin_clzl(x);};
+    inline int clz(unsigned long long int x){ return __builtin_clzll(x);};
+}}}
+//gcc __builtin_clz builtin count _number_ of leading zeroes
+static inline intptr_t __TBB_machine_lg( uintptr_t x ) {
+    return sizeof(x)*8 - tbb::internal::gcc_builtins::clz(x) -1 ;
+}
+
+static inline void __TBB_machine_or( volatile void *ptr, uintptr_t addend ) {
+    __sync_fetch_and_or(reinterpret_cast<volatile uintptr_t *>(ptr),addend);
+}
+
+static inline void __TBB_machine_and( volatile void *ptr, uintptr_t addend ) {
+    __sync_fetch_and_and(reinterpret_cast<volatile uintptr_t *>(ptr),addend);
+}
+
+
+typedef unsigned char __TBB_Flag;
+
+typedef __TBB_atomic __TBB_Flag __TBB_atomic_flag;
+
+inline bool __TBB_machine_try_lock_byte( __TBB_atomic_flag &flag ) {
+    return __sync_lock_test_and_set(&flag,1)==0;
+}
+
+inline void __TBB_machine_unlock_byte( __TBB_atomic_flag &flag ) {
+    __sync_lock_release(&flag);
+}
+
+// Machine specific atomic operations
+#define __TBB_AtomicOR(P,V)     __TBB_machine_or(P,V)
+#define __TBB_AtomicAND(P,V)    __TBB_machine_and(P,V)
+
+#define __TBB_TryLockByte   __TBB_machine_try_lock_byte
+#define __TBB_UnlockByte    __TBB_machine_unlock_byte
+
+// Definition of other functions
+#define __TBB_Log2(V)           __TBB_machine_lg(V)
+
+#define __TBB_USE_GENERIC_FETCH_STORE                       1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
+
+#if __TBB_WORDSIZE==4
+    #define __TBB_USE_GENERIC_DWORD_LOAD_STORE              1
+#endif
+
+#if __TBB_x86_32 || __TBB_x86_64
+#include "gcc_itsx.h"
+#endif
diff --git a/dependencies64/tbb/include/tbb/machine/gcc_ia32_common.h b/dependencies64/tbb/include/tbb/machine/gcc_ia32_common.h
new file mode 100644 (file)
index 0000000..1c4dad0
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_machine_gcc_ia32_common_H
+#define __TBB_machine_gcc_ia32_common_H
+
+//TODO: Add a higher-level function, e.g. tbb::interal::log2(), into tbb_stddef.h, which
+//uses __TBB_Log2 and contains the assert and remove the assert from here and all other
+//platform-specific headers.
+//TODO: Check if use of gcc intrinsic gives a better chance for cross call optimizations
+template <typename T>
+static inline intptr_t __TBB_machine_lg( T x ) {
+    __TBB_ASSERT(x>0, "The logarithm of a non-positive value is undefined.");
+    uintptr_t j, i = x;
+    __asm__("bsr %1,%0" : "=r"(j) : "r"(i));
+    return j;
+}
+#define __TBB_Log2(V)  __TBB_machine_lg(V)
+
+#ifndef __TBB_Pause
+//TODO: check if raising a ratio of pause instructions to loop control instructions
+//(via e.g. loop unrolling) gives any benefit for HT.  E.g, the current implementation
+//does about 2 CPU-consuming instructions for every pause instruction.  Perhaps for
+//high pause counts it should use an unrolled loop to raise the ratio, and thus free
+//up more integer cycles for the other hyperthread.  On the other hand, if the loop is
+//unrolled too far, it won't fit in the core's loop cache, and thus take away
+//instruction decode slots from the other hyperthread.
+
+//TODO: check if use of gcc __builtin_ia32_pause intrinsic gives a "some how" better performing code
+static inline void __TBB_machine_pause( int32_t delay ) {
+    for (int32_t i = 0; i < delay; i++) {
+       __asm__ __volatile__("pause;");
+    }
+    return;
+}
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+#endif /* !__TBB_Pause */
+
+// API to retrieve/update FPU control setting
+#ifndef __TBB_CPU_CTL_ENV_PRESENT
+#define __TBB_CPU_CTL_ENV_PRESENT 1
+namespace tbb {
+namespace internal {
+class cpu_ctl_env {
+private:
+    int     mxcsr;
+    short   x87cw;
+    static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */
+public:
+    bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; }
+    void get_env() {
+    #if __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN
+        cpu_ctl_env loc_ctl;
+        __asm__ __volatile__ (
+                "stmxcsr %0\n\t"
+                "fstcw %1"
+                : "=m"(loc_ctl.mxcsr), "=m"(loc_ctl.x87cw)
+        );
+        *this = loc_ctl;
+    #else
+        __asm__ __volatile__ (
+                "stmxcsr %0\n\t"
+                "fstcw %1"
+                : "=m"(mxcsr), "=m"(x87cw)
+        );
+    #endif
+        mxcsr &= MXCSR_CONTROL_MASK;
+    }
+    void set_env() const {
+        __asm__ __volatile__ (
+                "ldmxcsr %0\n\t"
+                "fldcw %1"
+                : : "m"(mxcsr), "m"(x87cw)
+        );
+    }
+};
+} // namespace internal
+} // namespace tbb
+#endif /* !__TBB_CPU_CTL_ENV_PRESENT */
+
+#include "gcc_itsx.h"
+
+#endif /* __TBB_machine_gcc_ia32_common_H */
diff --git a/dependencies64/tbb/include/tbb/machine/gcc_itsx.h b/dependencies64/tbb/include/tbb/machine/gcc_itsx.h
new file mode 100644 (file)
index 0000000..8797165
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_itsx_H)
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#define __TBB_machine_gcc_itsx_H
+
+#define __TBB_OP_XACQUIRE 0xF2
+#define __TBB_OP_XRELEASE 0xF3
+#define __TBB_OP_LOCK     0xF0
+
+#define __TBB_STRINGIZE_INTERNAL(arg) #arg
+#define __TBB_STRINGIZE(arg) __TBB_STRINGIZE_INTERNAL(arg)
+
+#ifdef __TBB_x86_64
+#define __TBB_r_out "=r"
+#else
+#define __TBB_r_out "=q"
+#endif
+
+inline static uint8_t __TBB_machine_try_lock_elided( volatile uint8_t* lk )
+{
+    uint8_t value = 1;
+    __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XACQUIRE)"; lock; xchgb %0, %1;"
+                      : __TBB_r_out(value), "=m"(*lk)  : "0"(value), "m"(*lk) : "memory" );
+    return uint8_t(value^1);
+}
+
+inline static void __TBB_machine_try_lock_elided_cancel()
+{
+    // 'pause' instruction aborts HLE/RTM transactions
+    __asm__ volatile ("pause\n" : : : "memory" );
+}
+
+inline static void __TBB_machine_unlock_elided( volatile uint8_t* lk )
+{
+    __asm__ volatile (".byte " __TBB_STRINGIZE(__TBB_OP_XRELEASE)"; movb $0, %0" 
+                      : "=m"(*lk) : "m"(*lk) : "memory" );
+}
+
+#if __TBB_TSX_INTRINSICS_PRESENT
+#include <immintrin.h>
+
+#define __TBB_machine_is_in_transaction _xtest
+#define __TBB_machine_begin_transaction _xbegin
+#define __TBB_machine_end_transaction   _xend
+#define __TBB_machine_transaction_conflict_abort() _xabort(0xff)
+
+#else
+
+/*!
+ * Check if the instruction is executed in a transaction or not
+ */
+inline static bool __TBB_machine_is_in_transaction()
+{
+    int8_t res = 0;
+#if __TBB_x86_32
+    __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n"
+                      "setz %0" : "=q"(res) : : "memory" );
+#else
+    __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD6;\n"
+                      "setz %0" : "=r"(res) : : "memory" );
+#endif
+    return res==0;
+}
+
+/*!
+ * Enter speculative execution mode.
+ * @return -1 on success
+ *         abort cause ( or 0 ) on abort
+ */
+inline static uint32_t __TBB_machine_begin_transaction()
+{
+    uint32_t res = ~uint32_t(0);   // success value
+    __asm__ volatile ("1: .byte  0xC7; .byte 0xF8;\n"           //  XBEGIN <abort-offset>
+                      "   .long  2f-1b-6\n"                     //  2f-1b == difference in addresses of start 
+                                                                //  of XBEGIN and the MOVL
+                                                                //  2f - 1b - 6 == that difference minus the size of the
+                                                                //  XBEGIN instruction.  This is the abort offset to
+                                                                //  2: below.
+                      "    jmp   3f\n"                          //  success (leave -1 in res)
+                      "2:  movl  %%eax,%0\n"                    //  store failure code in res
+                      "3:"
+                      :"=r"(res):"0"(res):"memory","%eax");
+    return res;
+}
+
+/*!
+ * Attempt to commit/end transaction 
+ */
+inline static void __TBB_machine_end_transaction()
+{
+    __asm__ volatile (".byte 0x0F; .byte 0x01; .byte 0xD5" :::"memory");   // XEND
+}
+
+/*
+ * aborts with code 0xFF (lock already held)
+ */
+inline static void __TBB_machine_transaction_conflict_abort()
+{
+    __asm__ volatile (".byte 0xC6; .byte 0xF8; .byte 0xFF" :::"memory");
+}
+
+#endif /* __TBB_TSX_INTRINSICS_PRESENT */
index 2cd606e4626dbee3808d0bdfe1490ceae8c0e76e..57dfeb3368b261d6899b717f36bbf56f0bbb8b53 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
 
-    This file is part of Threading Building Blocks.
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
 
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 // TODO: revise by comparing with mac_ppc.h
@@ -35,7 +27,7 @@
 #define __TBB_machine_ibm_aix51_H
 
 #define __TBB_WORDSIZE 8
-#define __TBB_BIG_ENDIAN 1
+#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG // assumption based on operating system
 
 #include <stdint.h>
 #include <unistd.h>
@@ -55,11 +47,12 @@ void __TBB_machine_isync ();
 
 #define __TBB_Yield() sched_yield()
 
-#define __TBB_USE_GENERIC_PART_WORD_CAS             1
-#define __TBB_USE_GENERIC_FETCH_ADD                 1
-#define __TBB_USE_GENERIC_FETCH_STORE               1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
+#define __TBB_USE_GENERIC_PART_WORD_CAS                     1
+#define __TBB_USE_GENERIC_FETCH_ADD                         1
+#define __TBB_USE_GENERIC_FETCH_STORE                       1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 #if __GNUC__
     #define __TBB_control_consistency_helper() __asm__ __volatile__( "isync": : :"memory")
diff --git a/dependencies64/tbb/include/tbb/machine/icc_generic.h b/dependencies64/tbb/include/tbb/machine/icc_generic.h
new file mode 100644 (file)
index 0000000..c31a5a3
--- /dev/null
@@ -0,0 +1,258 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#if !defined(__TBB_machine_H) || defined(__TBB_machine_icc_generic_H)
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#if ! __TBB_ICC_BUILTIN_ATOMICS_PRESENT
+    #error "Intel C++ Compiler of at least 12.0 version is needed to use ICC intrinsics port"
+#endif
+
+#define __TBB_machine_icc_generic_H
+
+//ICC mimics the "native" target compiler
+#if _MSC_VER
+    #include "msvc_ia32_common.h"
+#else
+    #include "gcc_ia32_common.h"
+#endif
+
+//TODO: Make __TBB_WORDSIZE macro optional for ICC intrinsics port.
+//As compiler intrinsics are used for all the operations it is possible to do.
+
+#if __TBB_x86_32
+    #define __TBB_WORDSIZE 4
+#else
+    #define __TBB_WORDSIZE 8
+#endif
+#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
+
+//__TBB_compiler_fence() defined just in case, as it seems not to be used on its own anywhere else
+#if _MSC_VER
+    //TODO: any way to use same intrinsics on windows and linux?
+    #pragma intrinsic(_ReadWriteBarrier)
+    #define __TBB_compiler_fence()    _ReadWriteBarrier()
+#else
+    #define __TBB_compiler_fence()    __asm__ __volatile__("": : :"memory")
+#endif
+
+#ifndef __TBB_full_memory_fence
+#if _MSC_VER 
+    //TODO: any way to use same intrinsics on windows and linux?
+    #pragma intrinsic(_mm_mfence)
+    #define __TBB_full_memory_fence() _mm_mfence()
+#else
+    #define __TBB_full_memory_fence() __asm__ __volatile__("mfence": : :"memory")
+#endif
+#endif
+
+#define __TBB_control_consistency_helper() __TBB_compiler_fence()
+
+namespace tbb { namespace internal {
+//TODO: is there any way to reuse definition of memory_order enum from ICC instead of copy paste.
+//however it seems unlikely that ICC will silently change exact enum values, as they are defined
+//in the ISO exactly like this.
+//TODO: add test that exact values of the enum are same as in the ISO C++11
+typedef enum memory_order {
+    memory_order_relaxed, memory_order_consume, memory_order_acquire,
+    memory_order_release, memory_order_acq_rel, memory_order_seq_cst
+} memory_order;
+
+namespace icc_intrinsics_port {
+    template <typename T>
+    T convert_argument(T value){
+        return value;
+    }
+    //The overload below is needed to have explicit conversion of pointer to void* in argument list.
+    //compiler bug?
+    //TODO: add according broken macro and recheck with ICC 13.0 if the overload is still needed
+    template <typename T>
+    void* convert_argument(T* value){
+        return (void*)value;
+    }
+}
+//TODO: code below is a bit repetitive, consider simplifying it
+template <typename T, size_t S>
+struct machine_load_store {
+    static T load_with_acquire ( const volatile T& location ) {
+        return __atomic_load_explicit(&location, memory_order_acquire);
+    }
+    static void store_with_release ( volatile T &location, T value ) {
+        __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release);
+    }
+};
+
+template <typename T, size_t S>
+struct machine_load_store_relaxed {
+    static inline T load ( const T& location ) {
+        return __atomic_load_explicit(&location, memory_order_relaxed);
+    }
+    static inline void store (  T& location, T value ) {
+        __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed);
+    }
+};
+
+template <typename T, size_t S>
+struct machine_load_store_seq_cst {
+    static T load ( const volatile T& location ) {
+        return __atomic_load_explicit(&location, memory_order_seq_cst);
+    }
+
+    static void store ( volatile T &location, T value ) {
+        __atomic_store_explicit(&location, value, memory_order_seq_cst);
+    }
+};
+
+}} // namespace tbb::internal
+
+namespace tbb{ namespace internal { namespace icc_intrinsics_port{
+    typedef enum memory_order_map {
+        relaxed = memory_order_relaxed,
+        acquire = memory_order_acquire,
+        release = memory_order_release,
+        full_fence=  memory_order_seq_cst
+    } memory_order_map;
+}}}// namespace tbb::internal
+
+#define __TBB_MACHINE_DEFINE_ATOMICS(S,T,M)                                                     \
+inline T __TBB_machine_cmpswp##S##M( volatile void *ptr, T value, T comparand ) {               \
+    __atomic_compare_exchange_strong_explicit(                                                  \
+            (T*)ptr                                                                             \
+            ,&comparand                                                                         \
+            ,value                                                                              \
+            , tbb::internal::icc_intrinsics_port::M                                             \
+            , tbb::internal::icc_intrinsics_port::M);                                           \
+    return comparand;                                                                           \
+}                                                                                               \
+                                                                                                \
+inline T __TBB_machine_fetchstore##S##M(volatile void *ptr, T value) {                          \
+    return __atomic_exchange_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M);   \
+}                                                                                               \
+                                                                                                \
+inline T __TBB_machine_fetchadd##S##M(volatile void *ptr, T value) {                            \
+    return __atomic_fetch_add_explicit((T*)ptr, value, tbb::internal::icc_intrinsics_port::M);  \
+}                                                                                               \
+
+__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, full_fence)
+__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, acquire)
+__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, release)
+__TBB_MACHINE_DEFINE_ATOMICS(1,tbb::internal::int8_t, relaxed)
+
+__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, full_fence)
+__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, acquire)
+__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, release)
+__TBB_MACHINE_DEFINE_ATOMICS(2,tbb::internal::int16_t, relaxed)
+
+__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, full_fence)
+__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, acquire)
+__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, release)
+__TBB_MACHINE_DEFINE_ATOMICS(4,tbb::internal::int32_t, relaxed)
+
+__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, full_fence)
+__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, acquire)
+__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, release)
+__TBB_MACHINE_DEFINE_ATOMICS(8,tbb::internal::int64_t, relaxed)
+
+
+#undef __TBB_MACHINE_DEFINE_ATOMICS
+
+#define __TBB_USE_FENCED_ATOMICS                            1
+
+namespace tbb { namespace internal {
+#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
+__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence)
+__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence)
+
+__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(acquire)
+__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(release)
+
+__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(relaxed)
+__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(relaxed)
+
+template <typename T>
+struct machine_load_store<T,8> {
+    static T load_with_acquire ( const volatile T& location ) {
+        if( tbb::internal::is_aligned(&location,8)) {
+            return __atomic_load_explicit(&location, memory_order_acquire);
+        } else {
+            return __TBB_machine_generic_load8acquire(&location);
+        }
+    }
+    static void store_with_release ( volatile T &location, T value ) {
+        if( tbb::internal::is_aligned(&location,8)) {
+            __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_release);
+        } else {
+            return __TBB_machine_generic_store8release(&location,value);
+        }
+    }
+};
+
+template <typename T>
+struct machine_load_store_relaxed<T,8> {
+    static T load( const volatile T& location ) {
+        if( tbb::internal::is_aligned(&location,8)) {
+            return __atomic_load_explicit(&location, memory_order_relaxed);
+        } else {
+            return __TBB_machine_generic_load8relaxed(&location);
+        }
+    }
+    static void store( volatile T &location, T value ) {
+        if( tbb::internal::is_aligned(&location,8)) {
+            __atomic_store_explicit(&location, icc_intrinsics_port::convert_argument(value), memory_order_relaxed);
+        } else {
+            return __TBB_machine_generic_store8relaxed(&location,value);
+        }
+    }
+};
+
+template <typename T >
+struct machine_load_store_seq_cst<T,8> {
+    static T load ( const volatile T& location ) {
+        if( tbb::internal::is_aligned(&location,8)) {
+            return __atomic_load_explicit(&location, memory_order_seq_cst);
+        } else {
+            return __TBB_machine_generic_load8full_fence(&location);
+        }
+
+    }
+
+    static void store ( volatile T &location, T value ) {
+        if( tbb::internal::is_aligned(&location,8)) {
+            __atomic_store_explicit(&location, value, memory_order_seq_cst);
+        } else {
+            return __TBB_machine_generic_store8full_fence(&location,value);
+        }
+
+    }
+};
+
+#endif
+}} // namespace tbb::internal
+template <typename T>
+inline void __TBB_machine_OR( T *operand, T addend ) {
+    __atomic_fetch_or_explicit(operand, addend, tbb::internal::memory_order_seq_cst);
+}
+
+template <typename T>
+inline void __TBB_machine_AND( T *operand, T addend ) {
+    __atomic_fetch_and_explicit(operand, addend, tbb::internal::memory_order_seq_cst);
+}
+
index 2efa77ddedf08a56eb8760936befc344a13c7f5c..53eeeafc3af20b370aca1bde1857836285ee8b9f 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_machine_H
@@ -33,6 +25,7 @@
 #include <sched.h>
 #define __TBB_Yield()  sched_yield()
 
+#include <unistd.h>
 /* Futex definitions */
 #include <sys/syscall.h>
 
@@ -64,7 +57,7 @@ namespace tbb {
 namespace internal {
 
 inline int futex_wait( void *futex, int comparand ) {
-    int r = ::syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 );
+    int r = syscall( SYS_futex,futex,__TBB_FUTEX_WAIT,comparand,NULL,NULL,0 );
 #if TBB_USE_ASSERT
     int e = errno;
     __TBB_ASSERT( r==0||r==EWOULDBLOCK||(r==-1&&(e==EAGAIN||e==EINTR)), "futex_wait failed." );
index 32183412ab80f8f494ec6d8fcc335fc437965d3b..27def2ff5476e8ef423bcccc15b642afe2337c6d 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia32_H)
 #define __TBB_machine_linux_ia32_H
 
 #include <stdint.h>
-#include <unistd.h>
+#include "gcc_ia32_common.h"
 
 #define __TBB_WORDSIZE 4
-#define __TBB_BIG_ENDIAN 0
+#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
 
 #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory")
 #define __TBB_control_consistency_helper() __TBB_compiler_fence()
@@ -92,8 +84,18 @@ __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"l","=r")
 #pragma warning( disable: 998 )
 #endif
 
-static inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand )
-{
+#if __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN
+#define  __TBB_IA32_CAS8_NOINLINE  __attribute__ ((noinline))
+#else
+#define  __TBB_IA32_CAS8_NOINLINE
+#endif
+
+static inline __TBB_IA32_CAS8_NOINLINE int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t comparand )  {
+//TODO: remove the extra part of condition once __TBB_GCC_BUILTIN_ATOMICS_PRESENT is lowered to gcc version 4.1.2
+#if (__TBB_GCC_BUILTIN_ATOMICS_PRESENT || (__TBB_GCC_VERSION >= 40102)) && !__TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN
+    return __sync_val_compare_and_swap( reinterpret_cast<volatile int64_t*>(ptr), comparand, value );
+#else /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */
+    //TODO: look like ICC 13.0 has some issues with this code, investigate it more deeply
     int64_t result;
     union {
         int64_t i64;
@@ -139,18 +141,15 @@ static inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value,
     );
 #endif /* __PIC__ */
     return result;
+#endif /* !__TBB_GCC_BUILTIN_ATOMICS_PRESENT */
 }
 
+#undef __TBB_IA32_CAS8_NOINLINE
+
 #if __INTEL_COMPILER
 #pragma warning( pop )
 #endif // warning 998 is back
 
-static inline int32_t __TBB_machine_lg( uint32_t x ) {
-    int32_t j;
-    __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x));
-    return j;
-}
-
 static inline void __TBB_machine_or( volatile void *ptr, uint32_t addend ) {
     __asm__ __volatile__("lock\norl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory");
 }
@@ -159,24 +158,44 @@ static inline void __TBB_machine_and( volatile void *ptr, uint32_t addend ) {
     __asm__ __volatile__("lock\nandl %1,%0" : "=m"(*(__TBB_VOLATILE uint32_t *)ptr) : "r"(addend), "m"(*(__TBB_VOLATILE uint32_t *)ptr) : "memory");
 }
 
-static inline void __TBB_machine_pause( int32_t delay ) {
-    for (int32_t i = 0; i < delay; i++) {
-       __asm__ __volatile__("pause;");
-    }
-    return;
-}   
+//TODO: Check if it possible and profitable for IA-32 architecture on (Linux* and Windows*)
+//to use of 64-bit load/store via floating point registers together with full fence
+//for sequentially consistent load/store, instead of CAS.
 
-static inline int64_t __TBB_machine_load8 (const volatile void *ptr) {
+#if __clang__
+#define __TBB_fildq  "fildll"
+#define __TBB_fistpq "fistpll"
+#else
+#define __TBB_fildq  "fildq"
+#define __TBB_fistpq "fistpq"
+#endif
+
+static inline int64_t __TBB_machine_aligned_load8 (const volatile void *ptr) {
+    __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_load8 should be used with 8 byte aligned locations only \n");
     int64_t result;
-    if( ((uint32_t)ptr&7u)==0 ) {
-        // Aligned load
-        __asm__ __volatile__ ( "fildq %1\n\t"
-                               "fistpq %0" :  "=m"(result) : "m"(*(const __TBB_VOLATILE uint64_t*)ptr) : "memory" );
+    __asm__ __volatile__ ( __TBB_fildq  " %1\n\t"
+                           __TBB_fistpq " %0" :  "=m"(result) : "m"(*(const __TBB_VOLATILE uint64_t*)ptr) : "memory" );
+    return result;
+}
+
+static inline void __TBB_machine_aligned_store8 (volatile void *ptr, int64_t value ) {
+    __TBB_ASSERT(tbb::internal::is_aligned(ptr,8),"__TBB_machine_aligned_store8 should be used with 8 byte aligned locations only \n");
+    // Aligned store
+    __asm__ __volatile__ ( __TBB_fildq  " %1\n\t"
+                           __TBB_fistpq " %0" :  "=m"(*(__TBB_VOLATILE int64_t*)ptr) : "m"(value) : "memory" );
+}
+
+static inline int64_t __TBB_machine_load8 (const volatile void *ptr) {
+#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
+    if( tbb::internal::is_aligned(ptr,8)) {
+#endif
+        return __TBB_machine_aligned_load8(ptr);
+#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
     } else {
         // Unaligned load
-        result = __TBB_machine_cmpswp8(const_cast<void*>(ptr),0,0);
+        return __TBB_machine_cmpswp8(const_cast<void*>(ptr),0,0);
     }
-    return result;
+#endif
 }
 
 //! Handles misaligned 8-byte store
@@ -185,10 +204,11 @@ extern "C" void __TBB_machine_store8_slow( volatile void *ptr, int64_t value );
 extern "C" void __TBB_machine_store8_slow_perf_warning( volatile void *ptr );
 
 static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) {
-    if( ((uint32_t)ptr&7u)==0 ) {
-        // Aligned store
-        __asm__ __volatile__ ( "fildq %1\n\t"
-                               "fistpq %0" :  "=m"(*(__TBB_VOLATILE int64_t*)ptr) : "m"(value) : "memory" );
+#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
+    if( tbb::internal::is_aligned(ptr,8)) {
+#endif
+        __TBB_machine_aligned_store8(ptr,value);
+#if __TBB_FORCE_64BIT_ALIGNMENT_BROKEN
     } else {
         // Unaligned store
 #if TBB_USE_PERFORMANCE_WARNINGS
@@ -196,41 +216,17 @@ static inline void __TBB_machine_store8(volatile void *ptr, int64_t value) {
 #endif /* TBB_USE_PERFORMANCE_WARNINGS */
         __TBB_machine_store8_slow(ptr,value);
     }
+#endif
 }
  
 // Machine specific atomic operations
 #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V)
 #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V)
 
-// Definition of other functions
-#define __TBB_Pause(V) __TBB_machine_pause(V)
-#define __TBB_Log2(V)  __TBB_machine_lg(V)
-
-#define __TBB_USE_GENERIC_DWORD_FETCH_ADD           1
-#define __TBB_USE_GENERIC_DWORD_FETCH_STORE         1
-#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE   1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
-
-// API to retrieve/update FPU control setting
-#define __TBB_CPU_CTL_ENV_PRESENT 1
+#define __TBB_USE_GENERIC_DWORD_FETCH_ADD                   1
+#define __TBB_USE_GENERIC_DWORD_FETCH_STORE                 1
+#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE           1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
-struct __TBB_cpu_ctl_env_t {
-    int     mxcsr;
-    short   x87cw;
-};
-
-inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) {
-    __asm__ __volatile__ (
-            "stmxcsr %0\n\t"
-            "fstcw   %1"
-            : "=m"(ctl->mxcsr), "=m"(ctl->x87cw)
-    );
-}
-inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) {
-    __asm__ __volatile__ (
-            "ldmxcsr %0\n\t"
-            "fldcw   %1"
-            : : "m"(ctl->mxcsr), "m"(ctl->x87cw)
-    );
-}
index 7d92936315081c7c689e5c2e4c5122e066fa35af..a9f386acc0e0253329d57c6c047c047335fa7e4d 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_ia64_H)
 #define __TBB_machine_linux_ia64_H
 
 #include <stdint.h>
-#include <unistd.h>
 #include <ia64intrin.h>
 
 #define __TBB_WORDSIZE 8
-#define __TBB_BIG_ENDIAN 0
+#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
 
 #if __INTEL_COMPILER
     #define __TBB_compiler_fence()
@@ -56,6 +47,7 @@
 #endif /* !__INTEL_COMPILER */
 
 // Most of the functions will be in a .s file
+// TODO: revise dynamic_link, memory pools and etc. if the library dependency is removed.
 
 extern "C" {
     int8_t __TBB_machine_fetchadd1__TBB_full_fence (volatile void *ptr, int8_t addend);
@@ -176,8 +168,9 @@ namespace internal {
 
 #undef __TBB_MACHINE_DEFINE_ATOMICS
 
-#define __TBB_USE_FENCED_ATOMICS 1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE 1
+#define __TBB_USE_FENCED_ATOMICS                            1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 // Definition of Lock functions
 #define __TBB_TryLockByte(P) __TBB_machine_trylockbyte(P)
index 8e34e08e136f104866c9201857e13419b60a27e1..6fe018b83c1d28f1ad29e02a0910a73e5af2d0cf 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_linux_intel64_H)
 #define __TBB_machine_linux_intel64_H
 
 #include <stdint.h>
-#include <unistd.h>
+#include "gcc_ia32_common.h"
 
 #define __TBB_WORDSIZE 8
-#define __TBB_BIG_ENDIAN 0
+#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
 
 #define __TBB_compiler_fence() __asm__ __volatile__("": : :"memory")
 #define __TBB_control_consistency_helper() __TBB_compiler_fence()
@@ -78,7 +70,7 @@ static inline  T __TBB_machine_fetchstore##S(volatile void *ptr, T value)
                           : "memory");                                               \
     return result;                                                                   \
 }                                                                                    \
-                                                                                     
+
 __TBB_MACHINE_DEFINE_ATOMICS(1,int8_t,"")
 __TBB_MACHINE_DEFINE_ATOMICS(2,int16_t,"")
 __TBB_MACHINE_DEFINE_ATOMICS(4,int32_t,"")
@@ -86,71 +78,19 @@ __TBB_MACHINE_DEFINE_ATOMICS(8,int64_t,"q")
 
 #undef __TBB_MACHINE_DEFINE_ATOMICS
 
-static inline int64_t __TBB_machine_lg( uint64_t x ) {
-    int64_t j;
-    __asm__ ("bsr %1,%0" : "=r"(j) : "r"(x));
-    return j;
-}
-
-static inline void __TBB_machine_or( volatile void *ptr, uint64_t addend ) {
-    __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(addend), "m"(*(volatile uint64_t*)ptr) : "memory");
+static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) {
+    __asm__ __volatile__("lock\norq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory");
 }
 
-static inline void __TBB_machine_and( volatile void *ptr, uint64_t addend ) {
-    __asm__ __volatile__("lock\nandq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(addend), "m"(*(volatile uint64_t*)ptr) : "memory");
+static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) {
+    __asm__ __volatile__("lock\nandq %1,%0" : "=m"(*(volatile uint64_t*)ptr) : "r"(value), "m"(*(volatile uint64_t*)ptr) : "memory");
 }
 
 #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V)
 #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V)
 
-// Definition of other functions
-#ifndef __TBB_Pause
-static inline void __TBB_machine_pause( int32_t delay ) {
-    for (int32_t i = 0; i < delay; i++) {
-       __asm__ __volatile__("pause;");
-    }
-    return;
-}
-#define __TBB_Pause(V) __TBB_machine_pause(V)
-#endif /* !__TBB_Pause */
-
-#define __TBB_Log2(V)  __TBB_machine_lg(V)
-
-#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE   1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
-
-// API to retrieve/update FPU control setting
-#ifndef __TBB_CPU_CTL_ENV_PRESENT
-#define __TBB_CPU_CTL_ENV_PRESENT 1
-
-struct __TBB_cpu_ctl_env_t {
-    int     mxcsr;
-    short   x87cw;
-};
-
-inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) {
-#if __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN
-    __TBB_cpu_ctl_env_t loc_ctl;
-    __asm__ __volatile__ (
-            "stmxcsr %0\n\t"
-            "fstcw %1"
-            : "=m"(loc_ctl.mxcsr), "=m"(loc_ctl.x87cw)
-    );
-    *ctl = loc_ctl;
-#else
-    __asm__ __volatile__ (
-            "stmxcsr %0\n\t"
-            "fstcw %1"
-            : "=m"(ctl->mxcsr), "=m"(ctl->x87cw)
-    );
-#endif
-}
-inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) {
-    __asm__ __volatile__ (
-            "ldmxcsr %0\n\t"
-            "fldcw %1"
-            : : "m"(ctl->mxcsr), "m"(ctl->x87cw)
-    );
-}
-#endif /* !__TBB_CPU_CTL_ENV_PRESENT */
+#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE           1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
+
index bb7bd8a1196f6994389bff3b3bfde23dd459f50d..2f12c9817915c8f285628d361653a0b2e760784d 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_gcc_power_H)
     #define __TBB_WORDSIZE 4
 #endif
 
+// Traditionally Power Architecture is big-endian.
+// Little-endian could be just an address manipulation (compatibility with TBB not verified),
+// or normal little-endian (on more recent systems). Embedded PowerPC systems may support
+// page-specific endianness, but then one endianness must be hidden from TBB so that it still sees only one.
+#if __BIG_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
+#elif __LITTLE_ENDIAN__ || (defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
+#elif defined(__BYTE_ORDER__)
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
+#else
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT
+#endif
+
 // On Power Architecture, (lock-free) 64-bit atomics require 64-bit hardware:
 #if __TBB_WORDSIZE==8
     // Do not change the following definition, because TBB itself will use 64-bit atomics in 64-bit builds.
     #define __TBB_64BIT_ATOMICS 1
 #elif __bgp__
-    // Do not change the following definition on known 32-bit hardware.
+    // Do not change the following definition, because this is known 32-bit hardware.
     #define __TBB_64BIT_ATOMICS 0
 #else
     // To enable 64-bit atomics in 32-bit builds, set the value below to 1 instead of 0.
@@ -148,6 +154,7 @@ inline int64_t __TBB_machine_cmpswp8 (volatile void *ptr, int64_t value, int64_t
                          );
     return result;
 }
+
 #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */
 
 #define __TBB_MACHINE_DEFINE_LOAD_STORE(S,ldx,stx,cmpx)                                                       \
@@ -275,14 +282,16 @@ namespace internal {
 
 #undef __TBB_MACHINE_DEFINE_LOAD_STORE
 
-#define __TBB_USE_GENERIC_PART_WORD_CAS 1
-#define __TBB_USE_GENERIC_FETCH_ADD     1
-#define __TBB_USE_GENERIC_FETCH_STORE   1
+#define __TBB_USE_GENERIC_PART_WORD_CAS                     1
+#define __TBB_USE_GENERIC_FETCH_ADD                         1
+#define __TBB_USE_GENERIC_FETCH_STORE                       1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 #define __TBB_control_consistency_helper() __asm__ __volatile__("isync": : :"memory")
 #define __TBB_full_memory_fence()          __asm__ __volatile__( "sync": : :"memory")
 
 static inline intptr_t __TBB_machine_lg( uintptr_t x ) {
+    __TBB_ASSERT(x, "__TBB_Log2(0) undefined");
     // cntlzd/cntlzw starts counting at 2^63/2^31 (ignoring any higher-order bits), and does not affect cr0
 #if __TBB_WORDSIZE==8
     __asm__ __volatile__ ("cntlzd %0,%0" : "+r"(x));
index dd12779684411068ac0ef76780caf225329b8ae9..dffcea5d7934dca80eeb9eb50fe56d55cc4022e7 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_macos_common_H)
@@ -56,17 +48,13 @@ static inline int __TBB_macos_available_cpu() {
     #define __TBB_UnknownArchitecture 1
 #endif
 
-#if __TBB_UnknownArchitecture || __TBB_WORDSIZE==4
-// In case of IA32 this is a workaround for compiler bugs triggered by inline
-// assembly implementation of __TBB_machine_cmpswp8 in linux_ia32.h, which may
-// lead to incorrect codegen (gcc) or compilation failures (any icc including 12.0.4).
-
+#if __TBB_UnknownArchitecture
 // Implementation of atomic operations based on OS provided primitives
 #include <libkern/OSAtomic.h>
 
 static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t value, int64_t comparand)
 {
-    __TBB_ASSERT( !((uintptr_t)ptr&0x7), "address not properly aligned for Mac OS atomics");
+    __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for OS X* atomics");
     int64_t* address = (int64_t*)ptr;
     while( !OSAtomicCompareAndSwap64Barrier(comparand, value, address) ){
 #if __TBB_WORDSIZE==8
@@ -81,7 +69,7 @@ static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t valu
 
 #define __TBB_machine_cmpswp8 __TBB_machine_cmpswp8_OsX
 
-#endif /* __TBB_UnknownArchitecture || __TBB_WORDSIZE==4 */
+#endif /* __TBB_UnknownArchitecture */
 
 #if __TBB_UnknownArchitecture
 
@@ -89,7 +77,15 @@ static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t valu
 #define __TBB_WORDSIZE 4
 #endif
 
-#define __TBB_BIG_ENDIAN __BIG_ENDIAN__
+#ifdef __TBB_ENDIANNESS
+    // Already determined based on hardware architecture.
+#elif __BIG_ENDIAN__
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
+#elif __LITTLE_ENDIAN__
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
+#else
+    #define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
+#endif
 
 /** As this generic implementation has absolutely no information about underlying
     hardware, its performance most likely will be sub-optimal because of full memory
@@ -103,7 +99,7 @@ static inline int64_t __TBB_machine_cmpswp8_OsX(volatile void *ptr, int64_t valu
 
 static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, int32_t comparand)
 {
-    __TBB_ASSERT( !((uintptr_t)ptr&0x3), "address not properly aligned for Mac OS atomics");
+    __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for OS X* atomics");
     int32_t* address = (int32_t*)ptr;
     while( !OSAtomicCompareAndSwap32Barrier(comparand, value, address) ){
         int32_t snapshot = *address;
@@ -114,23 +110,24 @@ static inline int32_t __TBB_machine_cmpswp4(volatile void *ptr, int32_t value, i
 
 static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend)
 {
-    __TBB_ASSERT( !((uintptr_t)ptr&0x3), "address not properly aligned for Mac OS atomics");
+    __TBB_ASSERT( tbb::internal::is_aligned(ptr,4), "address not properly aligned for OS X* atomics");
     return OSAtomicAdd32Barrier(addend, (int32_t*)ptr) - addend;
 }
 
 static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend)
 {
-    __TBB_ASSERT( !((uintptr_t)ptr&0x7), "address not properly aligned for Mac OS atomics");
+    __TBB_ASSERT( tbb::internal::is_aligned(ptr,8), "address not properly aligned for OS X* atomics");
     return OSAtomicAdd64Barrier(addend, (int64_t*)ptr) - addend;
 }
 
-#define __TBB_USE_GENERIC_PART_WORD_CAS             1
-#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD       1
-#define __TBB_USE_GENERIC_FETCH_STORE               1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
+#define __TBB_USE_GENERIC_PART_WORD_CAS                     1
+#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD               1
+#define __TBB_USE_GENERIC_FETCH_STORE                       1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
 #if __TBB_WORDSIZE == 4
-    #define __TBB_USE_GENERIC_DWORD_LOAD_STORE      1
+    #define __TBB_USE_GENERIC_DWORD_LOAD_STORE              1
 #endif
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 #endif /* __TBB_UnknownArchitecture */
diff --git a/dependencies64/tbb/include/tbb/machine/mic_common.h b/dependencies64/tbb/include/tbb/machine/mic_common.h
new file mode 100644 (file)
index 0000000..1f522da
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_mic_common_H
+#define __TBB_mic_common_H
+
+#ifndef __TBB_machine_H
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#if ! __TBB_DEFINE_MIC
+    #error mic_common.h should be included only when building for Intel(R) Many Integrated Core Architecture
+#endif
+
+#ifndef __TBB_PREFETCHING
+#define __TBB_PREFETCHING 1
+#endif
+#if __TBB_PREFETCHING
+#include <immintrin.h>
+#define __TBB_cl_prefetch(p) _mm_prefetch((const char*)p, _MM_HINT_T1)
+#define __TBB_cl_evict(p) _mm_clevict(p, _MM_HINT_T1)
+#endif
+
+/** Intel(R) Many Integrated Core Architecture does not support mfence and pause instructions **/
+#define __TBB_full_memory_fence() __asm__ __volatile__("lock; addl $0,(%%rsp)":::"memory")
+#define __TBB_Pause(x) _mm_delay_32(16*(x))
+#define __TBB_STEALING_PAUSE 1500/16
+#include <sched.h>
+#define __TBB_Yield() sched_yield()
+
+// low-level timing intrinsic and its type
+#define __TBB_machine_time_stamp() _rdtsc()
+typedef uint64_t machine_tsc_t;
+
+/** Specifics **/
+#define __TBB_STEALING_ABORT_ON_CONTENTION 1
+#define __TBB_YIELD2P 1
+#define __TBB_HOARD_NONLOCAL_TASKS 1
+
+#if ! ( __FreeBSD__ || __linux__ )
+    #error Intel(R) Many Integrated Core Compiler does not define __FreeBSD__ or __linux__ anymore. Check for the __TBB_XXX_BROKEN defined under __FreeBSD__ or __linux__.
+#endif /* ! ( __FreeBSD__ || __linux__ ) */
+
+#endif /* __TBB_mic_common_H */
diff --git a/dependencies64/tbb/include/tbb/machine/msvc_armv7.h b/dependencies64/tbb/include/tbb/machine/msvc_armv7.h
new file mode 100644 (file)
index 0000000..b96511c
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#if !defined(__TBB_machine_H) || defined(__TBB_msvc_armv7_H)
+#error Do not #include this internal file directly; use public TBB headers instead.
+#endif
+
+#define __TBB_msvc_armv7_H
+
+#include <intrin.h>
+#include <float.h>
+
+#define __TBB_WORDSIZE 4
+
+#define __TBB_ENDIANNESS __TBB_ENDIAN_UNSUPPORTED
+
+#if defined(TBB_WIN32_USE_CL_BUILTINS)
+// We can test this on _M_IX86
+#pragma intrinsic(_ReadWriteBarrier)
+#pragma intrinsic(_mm_mfence)
+#define __TBB_compiler_fence()    _ReadWriteBarrier()
+#define __TBB_full_memory_fence() _mm_mfence()
+#define __TBB_control_consistency_helper() __TBB_compiler_fence()
+#define __TBB_acquire_consistency_helper() __TBB_compiler_fence()
+#define __TBB_release_consistency_helper() __TBB_compiler_fence()
+#else
+//Now __dmb(_ARM_BARRIER_SY) is used for both compiler and memory fences
+//This might be changed later after testing
+#define __TBB_compiler_fence()    __dmb(_ARM_BARRIER_SY)
+#define __TBB_full_memory_fence() __dmb(_ARM_BARRIER_SY)
+#define __TBB_control_consistency_helper() __TBB_compiler_fence()
+#define __TBB_acquire_consistency_helper() __TBB_full_memory_fence()
+#define __TBB_release_consistency_helper() __TBB_full_memory_fence()
+#endif
+
+//--------------------------------------------------
+// Compare and swap
+//--------------------------------------------------
+
+/**
+ * Atomic CAS for 32 bit values, if *ptr==comparand, then *ptr=value, returns *ptr
+ * @param ptr pointer to value in memory to be swapped with value if *ptr==comparand
+ * @param value value to assign *ptr to if *ptr==comparand
+ * @param comparand value to compare with *ptr
+ * @return value originally in memory at ptr, regardless of success
+*/
+
+#define __TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(S,T,F)                                               \
+inline T __TBB_machine_cmpswp##S( volatile void *ptr, T value, T comparand ) {                   \
+    return _InterlockedCompareExchange##F(reinterpret_cast<volatile T *>(ptr),value,comparand);  \
+}                                                                                                \
+
+#define __TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(S,T,F)                                             \
+inline T __TBB_machine_fetchadd##S( volatile void *ptr, T value ) {                              \
+    return _InterlockedExchangeAdd##F(reinterpret_cast<volatile T *>(ptr),value);                \
+}                                                                                                \
+
+__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(1,char,8)
+__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(2,short,16)
+__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(4,long,)
+__TBB_MACHINE_DEFINE_ATOMICS_CMPSWP(8,__int64,64)
+__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(4,long,)
+#if defined(TBB_WIN32_USE_CL_BUILTINS)
+// No _InterlockedExchangeAdd64 intrinsic on _M_IX86
+#define __TBB_64BIT_ATOMICS 0
+#else
+__TBB_MACHINE_DEFINE_ATOMICS_FETCHADD(8,__int64,64)
+#endif
+
+inline void __TBB_machine_pause (int32_t delay )
+{
+    while(delay>0)
+    {
+        __TBB_compiler_fence();
+        delay--;
+    }
+}
+
+// API to retrieve/update FPU control setting
+#define __TBB_CPU_CTL_ENV_PRESENT 1
+
+namespace tbb {
+namespace internal {
+
+template <typename T, size_t S>
+struct machine_load_store_relaxed {
+    static inline T load ( const volatile T& location ) {
+        const T value = location;
+
+        /*
+        * An extra memory barrier is required for errata #761319
+        * Please see http://infocenter.arm.com/help/topic/com.arm.doc.uan0004a
+        */
+        __TBB_acquire_consistency_helper();
+        return value;
+    }
+
+    static inline void store ( volatile T& location, T value ) {
+        location = value;
+    }
+};
+
+class cpu_ctl_env {
+private:
+    unsigned int my_ctl;
+public:
+    bool operator!=( const cpu_ctl_env& ctl ) const { return my_ctl != ctl.my_ctl; }
+    void get_env() { my_ctl = _control87(0, 0); }
+    void set_env() const { _control87( my_ctl, ~0U ); }
+};
+
+} // namespace internal
+} // namespaces tbb
+
+// Machine specific atomic operations
+#define __TBB_CompareAndSwap4(P,V,C) __TBB_machine_cmpswp4(P,V,C)
+#define __TBB_CompareAndSwap8(P,V,C) __TBB_machine_cmpswp8(P,V,C)
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+
+// Use generics for some things
+#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE               1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD                   1
+#define __TBB_USE_GENERIC_PART_WORD_FETCH_STORE                 1
+#define __TBB_USE_GENERIC_FETCH_STORE                           1
+#define __TBB_USE_GENERIC_DWORD_LOAD_STORE                      1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE     1
+
+#if defined(TBB_WIN32_USE_CL_BUILTINS)
+#if !__TBB_WIN8UI_SUPPORT
+extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
+#define __TBB_Yield()  SwitchToThread()
+#else
+#include<thread>
+#define __TBB_Yield()  std::this_thread::yield()
+#endif
+#else
+#define __TBB_Yield() __yield()
+#endif
+
+// Machine specific atomic operations
+#define __TBB_AtomicOR(P,V)     __TBB_machine_OR(P,V)
+#define __TBB_AtomicAND(P,V)    __TBB_machine_AND(P,V)
+
+template <typename T1,typename T2>
+inline void __TBB_machine_OR( T1 *operand, T2 addend ) {
+    _InterlockedOr((long volatile *)operand, (long)addend);
+}
+
+template <typename T1,typename T2>
+inline void __TBB_machine_AND( T1 *operand, T2 addend ) {
+    _InterlockedAnd((long volatile *)operand, (long)addend);
+}
+
diff --git a/dependencies64/tbb/include/tbb/machine/msvc_ia32_common.h b/dependencies64/tbb/include/tbb/machine/msvc_ia32_common.h
new file mode 100644 (file)
index 0000000..184c3da
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_machine_msvc_ia32_common_H
+#define __TBB_machine_msvc_ia32_common_H
+
+#include <intrin.h>
+
+//TODO: consider moving this macro to tbb_config.h and used there MSVC asm is used
+#if  !_M_X64 || __INTEL_COMPILER
+    #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 1
+
+    #if _M_X64
+        #define __TBB_r(reg_name) r##reg_name
+    #else
+        #define __TBB_r(reg_name) e##reg_name
+    #endif
+#else
+    //MSVC in x64 mode does not accept inline assembler
+    #define __TBB_X86_MSVC_INLINE_ASM_AVAILABLE 0
+#endif
+
+#define __TBB_NO_X86_MSVC_INLINE_ASM_MSG "The compiler being used is not supported (outdated?)"
+
+#if (_MSC_VER >= 1300) || (__INTEL_COMPILER) //Use compiler intrinsic when available
+    #define __TBB_PAUSE_USE_INTRINSIC 1
+    #pragma intrinsic(_mm_pause)
+    namespace tbb { namespace internal { namespace intrinsics { namespace msvc {
+        static inline void __TBB_machine_pause (uintptr_t delay ) {
+            for (;delay>0; --delay )
+                _mm_pause();
+        }
+    }}}}
+#else
+    #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE
+        #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG
+    #endif
+
+    namespace tbb { namespace internal { namespace inline_asm { namespace msvc {
+        static inline void __TBB_machine_pause (uintptr_t delay ) {
+            _asm
+            {
+                mov __TBB_r(ax), delay
+              __TBB_L1:
+                pause
+                add __TBB_r(ax), -1
+                jne __TBB_L1
+            }
+            return;
+        }
+    }}}}
+#endif
+
+static inline void __TBB_machine_pause (uintptr_t delay ){
+    #if __TBB_PAUSE_USE_INTRINSIC
+        tbb::internal::intrinsics::msvc::__TBB_machine_pause(delay);
+    #else
+        tbb::internal::inline_asm::msvc::__TBB_machine_pause(delay);
+    #endif
+}
+
+//TODO: move this function to windows_api.h or to place where it is used
+#if (_MSC_VER<1400) && (!_WIN64) && (__TBB_X86_MSVC_INLINE_ASM_AVAILABLE)
+    static inline void* __TBB_machine_get_current_teb () {
+        void* pteb;
+        __asm mov eax, fs:[0x18]
+        __asm mov pteb, eax
+        return pteb;
+    }
+#endif
+
+#if ( _MSC_VER>=1400 && !defined(__INTEL_COMPILER) ) ||  (__INTEL_COMPILER>=1200)
+// MSVC did not have this intrinsic prior to VC8.
+// ICL 11.1 fails to compile a TBB example if __TBB_Log2 uses the intrinsic.
+    #define __TBB_LOG2_USE_BSR_INTRINSIC 1
+    #if _M_X64
+        #define __TBB_BSR_INTRINSIC _BitScanReverse64
+    #else
+        #define __TBB_BSR_INTRINSIC _BitScanReverse
+    #endif
+    #pragma intrinsic(__TBB_BSR_INTRINSIC)
+
+    namespace tbb { namespace internal { namespace intrinsics { namespace msvc {
+        inline uintptr_t __TBB_machine_lg( uintptr_t i ){
+            unsigned long j;
+            __TBB_BSR_INTRINSIC( &j, i );
+            return j;
+        }
+    }}}}
+#else
+    #if !__TBB_X86_MSVC_INLINE_ASM_AVAILABLE
+        #error __TBB_NO_X86_MSVC_INLINE_ASM_MSG
+    #endif
+
+    namespace tbb { namespace internal { namespace inline_asm { namespace msvc {
+        inline uintptr_t __TBB_machine_lg( uintptr_t i ){
+            uintptr_t j;
+            __asm
+            {
+                bsr __TBB_r(ax), i
+                mov j, __TBB_r(ax)
+            }
+            return j;
+        }
+    }}}}
+#endif
+
+static inline intptr_t __TBB_machine_lg( uintptr_t i ) {
+#if __TBB_LOG2_USE_BSR_INTRINSIC
+    return tbb::internal::intrinsics::msvc::__TBB_machine_lg(i);
+#else
+    return tbb::internal::inline_asm::msvc::__TBB_machine_lg(i);
+#endif
+}
+
+// API to retrieve/update FPU control setting
+#define __TBB_CPU_CTL_ENV_PRESENT 1
+
+namespace tbb { namespace internal { class cpu_ctl_env; } }
+#if __TBB_X86_MSVC_INLINE_ASM_AVAILABLE
+    inline void __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* ctl ) {
+        __asm {
+            __asm mov     __TBB_r(ax), ctl
+            __asm stmxcsr [__TBB_r(ax)]
+            __asm fstcw   [__TBB_r(ax)+4]
+        }
+    }
+    inline void __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* ctl ) {
+        __asm {
+            __asm mov     __TBB_r(ax), ctl
+            __asm ldmxcsr [__TBB_r(ax)]
+            __asm fldcw   [__TBB_r(ax)+4]
+        }
+    }
+#else
+    extern "C" {
+        void __TBB_EXPORTED_FUNC __TBB_get_cpu_ctl_env ( tbb::internal::cpu_ctl_env* );
+        void __TBB_EXPORTED_FUNC __TBB_set_cpu_ctl_env ( const tbb::internal::cpu_ctl_env* );
+    }
+#endif
+
+namespace tbb {
+namespace internal {
+class cpu_ctl_env {
+private:
+    int         mxcsr;
+    short       x87cw;
+    static const int MXCSR_CONTROL_MASK = ~0x3f; /* all except last six status bits */
+public:
+    bool operator!=( const cpu_ctl_env& ctl ) const { return mxcsr != ctl.mxcsr || x87cw != ctl.x87cw; }
+    void get_env() {
+        __TBB_get_cpu_ctl_env( this );
+        mxcsr &= MXCSR_CONTROL_MASK;
+    }
+    void set_env() const { __TBB_set_cpu_ctl_env( this ); }
+};
+} // namespace internal
+} // namespace tbb
+
+#if !__TBB_WIN8UI_SUPPORT
+extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
+#define __TBB_Yield()  SwitchToThread()
+#else
+#include<thread>
+#define __TBB_Yield()  std::this_thread::yield()
+#endif
+
+#define __TBB_Pause(V) __TBB_machine_pause(V)
+#define __TBB_Log2(V)  __TBB_machine_lg(V)
+
+#undef __TBB_r
+
+extern "C" {
+    __int8 __TBB_EXPORTED_FUNC __TBB_machine_try_lock_elided (volatile void* ptr);
+    void   __TBB_EXPORTED_FUNC __TBB_machine_unlock_elided (volatile void* ptr);
+
+    // 'pause' instruction aborts HLE/RTM transactions
+#if __TBB_PAUSE_USE_INTRINSIC
+    inline static void __TBB_machine_try_lock_elided_cancel() { _mm_pause(); }
+#else
+    inline static void __TBB_machine_try_lock_elided_cancel() { _asm pause; }
+#endif
+
+#if __TBB_TSX_INTRINSICS_PRESENT
+    #define __TBB_machine_is_in_transaction _xtest
+    #define __TBB_machine_begin_transaction _xbegin
+    #define __TBB_machine_end_transaction   _xend
+    // The value (0xFF) below comes from the
+    // Intel(R) 64 and IA-32 Architectures Optimization Reference Manual 12.4.5 lock not free
+    #define __TBB_machine_transaction_conflict_abort() _xabort(0xFF)
+#else
+    __int8           __TBB_EXPORTED_FUNC __TBB_machine_is_in_transaction();
+    unsigned __int32 __TBB_EXPORTED_FUNC __TBB_machine_begin_transaction();
+    void             __TBB_EXPORTED_FUNC __TBB_machine_end_transaction();
+    void             __TBB_EXPORTED_FUNC __TBB_machine_transaction_conflict_abort();
+#endif /* __TBB_TSX_INTRINSICS_PRESENT */
+}
+
+#endif /* __TBB_machine_msvc_ia32_common_H */
index e6e8079889056555b2840f77cb484aad301bac7a..1d4fbf74435ce8ffd4281d668a5be270798e2faf 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 
@@ -37,7 +29,9 @@
 #include <unistd.h>
 
 #define __TBB_WORDSIZE 8
-#define __TBB_BIG_ENDIAN 1
+// Big endian is assumed for SPARC.
+// While hardware may support page-specific bi-endianness, only big endian pages may be exposed to TBB  
+#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
 
 /** To those working on SPARC hardware. Consider relaxing acquire and release
     consistency helpers to no-op (as this port covers TSO mode only). **/
@@ -97,12 +91,12 @@ static inline int64_t __TBB_machine_cmpswp8(volatile void *ptr, int64_t value, i
  */
 static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend){
   int32_t result;
-  __asm__ __volatile__ (                                 
-                        "0:\t add\t %3, %4, %0\n"    // do addition
-                        "\t cas\t [%2], %3, %0\n"        // cas to store result in memory
-                        "\t cmp\t %3, %0\n"            // check if value from memory is original
-                        "\t bne,a,pn\t %%icc, 0b\n"        // if not try again
-                        "\t mov %0, %3\n"            // use branch delay slot to move new value in memory to be added
+  __asm__ __volatile__ (
+                        "0:\t add\t %3, %4, %0\n"           // do addition
+                        "\t cas\t [%2], %3, %0\n"           // cas to store result in memory
+                        "\t cmp\t %3, %0\n"                 // check if value from memory is original
+                        "\t bne,a,pn\t %%icc, 0b\n"         // if not try again
+                        "\t mov %0, %3\n"                   // use branch delay slot to move new value in memory to be added
                : "=&r"(result), "=m"(*(int32_t *)ptr)
                : "r"(ptr), "r"(*(int32_t *)ptr), "r"(addend), "m"(*(int32_t *)ptr)
                : "ccr", "memory");
@@ -118,11 +112,11 @@ static inline int32_t __TBB_machine_fetchadd4(volatile void *ptr, int32_t addend
 static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend){
   int64_t result;
   __asm__ __volatile__ (
-                        "0:\t add\t %3, %4, %0\n"    // do addition
-                        "\t casx\t [%2], %3, %0\n"        // cas to store result in memory
-                        "\t cmp\t %3, %0\n"            // check if value from memory is original
-                        "\t bne,a,pn\t %%xcc, 0b\n"        // if not try again
-                        "\t mov %0, %3\n"            // use branch delay slot to move new value in memory to be added
+                        "0:\t add\t %3, %4, %0\n"           // do addition
+                        "\t casx\t [%2], %3, %0\n"          // cas to store result in memory
+                        "\t cmp\t %3, %0\n"                 // check if value from memory is original
+                        "\t bne,a,pn\t %%xcc, 0b\n"         // if not try again
+                        "\t mov %0, %3\n"                   // use branch delay slot to move new value in memory to be added
                 : "=&r"(result), "=m"(*(int64_t *)ptr)
                 : "r"(ptr), "r"(*(int64_t *)ptr), "r"(addend), "m"(*(int64_t *)ptr)
                 : "ccr", "memory");
@@ -134,6 +128,7 @@ static inline int64_t __TBB_machine_fetchadd8(volatile void *ptr, int64_t addend
 //--------------------------------------------------------
 
 static inline int64_t __TBB_machine_lg( uint64_t x ) {
+    __TBB_ASSERT(x, "__TBB_Log2(0) undefined");
     uint64_t count;
     // one hot encode
     x |= (x >> 1);
@@ -149,33 +144,33 @@ static inline int64_t __TBB_machine_lg( uint64_t x ) {
 
 //--------------------------------------------------------
 
-static inline void __TBB_machine_or( volatile void *ptr, uint64_t addend ) {
+static inline void __TBB_machine_or( volatile void *ptr, uint64_t value ) {
   __asm__ __volatile__ (
-                        "0:\t or\t %2, %3, %%g1\n" // do addition
-                        "\t casx\t [%1], %2, %%g1\n"            // cas to store result in memory
-                        "\t cmp\t %2, %%g1\n"                   // check if value from memory is original
-                        "\t bne,a,pn\t %%xcc, 0b\n" // if not try again
-                        "\t mov %%g1, %2\n"                     // use branch delay slot to move new value in memory to be added
+                        "0:\t or\t %2, %3, %%g1\n"          // do operation
+                        "\t casx\t [%1], %2, %%g1\n"        // cas to store result in memory
+                        "\t cmp\t %2, %%g1\n"               // check if value from memory is original
+                        "\t bne,a,pn\t %%xcc, 0b\n"         // if not try again
+                        "\t mov %%g1, %2\n"                 // use branch delay slot to move new value in memory to be added
                 : "=m"(*(int64_t *)ptr)
-                : "r"(ptr), "r"(*(int64_t *)ptr), "r"(addend), "m"(*(int64_t *)ptr)
+                : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr)
                 : "ccr", "g1", "memory");
 }
 
-static inline void __TBB_machine_and( volatile void *ptr, uint64_t addend ) {
+static inline void __TBB_machine_and( volatile void *ptr, uint64_t value ) {
   __asm__ __volatile__ (
-                        "0:\t and\t %2, %3, %%g1\n"        // do addition
-                        "\t casx\t [%1], %2, %%g1\n"            // cas to store result in memory
-                        "\t cmp\t %2, %%g1\n"                   // check if value from memory is original
+                        "0:\t and\t %2, %3, %%g1\n"         // do operation
+                        "\t casx\t [%1], %2, %%g1\n"        // cas to store result in memory
+                        "\t cmp\t %2, %%g1\n"               // check if value from memory is original
                         "\t bne,a,pn\t %%xcc, 0b\n"         // if not try again
-                        "\t mov %%g1, %2\n"                     // use branch delay slot to move new value in memory to be added
+                        "\t mov %%g1, %2\n"                 // use branch delay slot to move new value in memory to be added
                 : "=m"(*(int64_t *)ptr)
-                : "r"(ptr), "r"(*(int64_t *)ptr), "r"(addend), "m"(*(int64_t *)ptr)
+                : "r"(ptr), "r"(*(int64_t *)ptr), "r"(value), "m"(*(int64_t *)ptr)
                 : "ccr", "g1", "memory");
 }
 
 
 static inline void __TBB_machine_pause( int32_t delay ) {
-    // do nothing, inlined, doesnt matter
+    // do nothing, inlined, doesn't matter
 }
 
 // put 0xff in memory location, return memory value,
@@ -191,11 +186,12 @@ static inline bool __TBB_machine_trylockbyte(unsigned char &flag){
     return result == 0;
 }
 
-#define __TBB_USE_GENERIC_PART_WORD_CAS             1
-#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD       1
-#define __TBB_USE_GENERIC_FETCH_STORE               1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
+#define __TBB_USE_GENERIC_PART_WORD_CAS                     1
+#define __TBB_USE_GENERIC_PART_WORD_FETCH_ADD               1
+#define __TBB_USE_GENERIC_FETCH_STORE                       1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 #define __TBB_AtomicOR(P,V) __TBB_machine_or(P,V)
 #define __TBB_AtomicAND(P,V) __TBB_machine_and(P,V)
index 37495602cef1b8c59e59ebc5dac44d359b244ca3..c0ccc24c5521210254a63fb39061922669200f8b 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_machine_windows_api_H
 
 #endif // _XBOX
 
-#if !defined(_WIN32_WINNT)
+#if _WIN32_WINNT < 0x0600
 // The following Windows API function is declared explicitly;
-// otherwise any user would have to specify /D_WIN32_WINNT=0x0400
-extern "C" BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION );
+// otherwise it fails to compile by VS2005.
+#if !defined(WINBASEAPI) || (_WIN32_WINNT < 0x0501 && _MSC_VER == 1400)
+#define __TBB_WINBASEAPI extern "C"
+#else
+#define __TBB_WINBASEAPI WINBASEAPI
+#endif
+__TBB_WINBASEAPI BOOL WINAPI TryEnterCriticalSection( LPCRITICAL_SECTION );
+__TBB_WINBASEAPI BOOL WINAPI InitializeCriticalSectionAndSpinCount( LPCRITICAL_SECTION, DWORD );
+// Overloading WINBASEAPI macro and using local functions missing in Windows XP/2003
+#define InitializeCriticalSectionEx inlineInitializeCriticalSectionEx
+#define CreateSemaphoreEx inlineCreateSemaphoreEx
+#define CreateEventEx inlineCreateEventEx
+inline BOOL WINAPI inlineInitializeCriticalSectionEx( LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD )
+{
+    return InitializeCriticalSectionAndSpinCount( lpCriticalSection, dwSpinCount );
+}
+inline HANDLE WINAPI inlineCreateSemaphoreEx( LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCTSTR lpName, DWORD, DWORD )
+{
+    return CreateSemaphore( lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName );
+}
+inline HANDLE WINAPI inlineCreateEventEx( LPSECURITY_ATTRIBUTES lpEventAttributes, LPCTSTR lpName, DWORD dwFlags, DWORD )
+{
+    BOOL manual_reset = dwFlags&0x00000001 ? TRUE : FALSE; // CREATE_EVENT_MANUAL_RESET
+    BOOL initial_set  = dwFlags&0x00000002 ? TRUE : FALSE; // CREATE_EVENT_INITIAL_SET
+    return CreateEvent( lpEventAttributes, manual_reset, initial_set, lpName );
+}
+#endif
+
+#if defined(RTL_SRWLOCK_INIT)
+#ifndef __TBB_USE_SRWLOCK
+// TODO: turn it on when bug 1952 will be fixed
+#define __TBB_USE_SRWLOCK 0
+#endif
 #endif
 
 #else
index 2902f18153e8804c086512cdeaf202dd01990964..3a38634c9eccb2cf07ec6f55d5d8e4971226c948 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_ia32_H)
 
 #define __TBB_machine_windows_ia32_H
 
+#include "msvc_ia32_common.h"
+
 #define __TBB_WORDSIZE 4
-#define __TBB_BIG_ENDIAN 0
+#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
 
-#if __INTEL_COMPILER
-    #define __TBB_compiler_fence() __asm { __asm nop }
-#elif _MSC_VER >= 1300
-    extern "C" void _ReadWriteBarrier();
+#if __INTEL_COMPILER && (__INTEL_COMPILER < 1100)
+    #define __TBB_compiler_fence()    __asm { __asm nop }
+    #define __TBB_full_memory_fence() __asm { __asm mfence }
+#elif _MSC_VER >= 1300 || __INTEL_COMPILER
     #pragma intrinsic(_ReadWriteBarrier)
-    #define __TBB_compiler_fence() _ReadWriteBarrier()
+    #pragma intrinsic(_mm_mfence)
+    #define __TBB_compiler_fence()    _ReadWriteBarrier()
+    #define __TBB_full_memory_fence() _mm_mfence()
 #else
     #error Unsupported compiler - need to define __TBB_{control,acquire,release}_consistency_helper to support it
 #endif
@@ -48,7 +44,6 @@
 #define __TBB_control_consistency_helper() __TBB_compiler_fence()
 #define __TBB_acquire_consistency_helper() __TBB_compiler_fence()
 #define __TBB_release_consistency_helper() __TBB_compiler_fence()
-#define __TBB_full_memory_fence()          __asm { __asm mfence }
 
 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
     // Workaround for overzealous compiler warnings in /Wp64 mode
@@ -64,6 +59,7 @@ extern "C" {
     __int64 __TBB_EXPORTED_FUNC __TBB_machine_load8 (const volatile void *ptr);
 }
 
+//TODO: use _InterlockedXXX intrinsics as they available since VC 2005
 #define __TBB_MACHINE_DEFINE_ATOMICS(S,T,U,A,C) \
 static inline T __TBB_machine_cmpswp##S ( volatile void * ptr, U value, U comparand ) { \
     T result; \
@@ -112,16 +108,6 @@ __TBB_MACHINE_DEFINE_ATOMICS(4, ptrdiff_t, ptrdiff_t, eax, ecx)
 
 #undef __TBB_MACHINE_DEFINE_ATOMICS
 
-static inline __int32 __TBB_machine_lg( unsigned __int64 i ) {
-    unsigned __int32 j;
-    __asm
-    {
-        bsr eax, i
-        mov j, eax
-    }
-    return j;
-}
-
 static inline void __TBB_machine_OR( volatile void *operand, __int32 addend ) {
    __asm 
    {
@@ -140,63 +126,19 @@ static inline void __TBB_machine_AND( volatile void *operand, __int32 addend ) {
    }
 }
 
-static inline void __TBB_machine_pause (__int32 delay ) {
-    _asm 
-    {
-        mov eax, delay
-      L1: 
-        pause
-        add eax, -1
-        jne L1  
-    }
-    return;
-}
-
 #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V)
 #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V)
 
-#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE   1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
-
-// Definition of other functions
-extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
-#define __TBB_Yield()  SwitchToThread()
-#define __TBB_Pause(V) __TBB_machine_pause(V)
-#define __TBB_Log2(V)  __TBB_machine_lg(V)
-
-#if defined(_MSC_VER)&&_MSC_VER<1400
-    static inline void* __TBB_machine_get_current_teb () {
-        void* pteb;
-        __asm mov eax, fs:[0x18]
-        __asm mov pteb, eax
-        return pteb;
-    }
-#endif
+//TODO: Check if it possible and profitable for IA-32 architecture on (Linux and Windows)
+//to use of 64-bit load/store via floating point registers together with full fence
+//for sequentially consistent load/store, instead of CAS.
+#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE           1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
+
 
 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
     #pragma warning (pop)
 #endif // warnings 4244, 4267 are back
 
-// API to retrieve/update FPU control setting
-#define __TBB_CPU_CTL_ENV_PRESENT 1
-
-struct __TBB_cpu_ctl_env_t {
-    int     mxcsr;
-    short   x87cw;
-};
-inline void __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* ctl ) {
-    __asm {
-        __asm mov     eax, ctl
-        __asm stmxcsr [eax]
-        __asm fstcw   [eax+4]
-    }
-}
-inline void __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* ctl ) {
-    __asm {
-        __asm mov     eax, ctl
-        __asm ldmxcsr [eax]
-        __asm fldcw   [eax+4]
-    }
-}
-
index 4d86eaf576dd79e3fc9106a152c9ceb11163d5b8..03795efd9b13a4fa12c5f65f9f76cc1d1de00cab 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #if !defined(__TBB_machine_H) || defined(__TBB_machine_windows_intel64_H)
 #define __TBB_machine_windows_intel64_H
 
 #define __TBB_WORDSIZE 8
-#define __TBB_BIG_ENDIAN 0
+#define __TBB_ENDIANNESS __TBB_ENDIAN_LITTLE
 
 #include <intrin.h>
+#include "msvc_ia32_common.h"
 
+//TODO: Use _InterlockedXXX16 intrinsics for 2 byte operations
 #if !__INTEL_COMPILER
     #pragma intrinsic(_InterlockedOr64)
     #pragma intrinsic(_InterlockedAnd64)
     #pragma intrinsic(_InterlockedExchangeAdd64)
     #pragma intrinsic(_InterlockedExchange)
     #pragma intrinsic(_InterlockedExchange64)
-#endif /* !defined(__INTEL_COMPILER) */
+#endif /* !(__INTEL_COMPILER) */
 
-#if __INTEL_COMPILER
+#if __INTEL_COMPILER && (__INTEL_COMPILER < 1100)
     #define __TBB_compiler_fence()    __asm { __asm nop }
     #define __TBB_full_memory_fence() __asm { __asm mfence }
-#elif _MSC_VER >= 1300
-    extern "C" void _ReadWriteBarrier();
+#elif _MSC_VER >= 1300 || __INTEL_COMPILER
     #pragma intrinsic(_ReadWriteBarrier)
     #pragma intrinsic(_mm_mfence)
     #define __TBB_compiler_fence()    _ReadWriteBarrier()
@@ -72,7 +65,6 @@ extern "C" {
     __int16 __TBB_EXPORTED_FUNC __TBB_machine_cmpswp2 (volatile void *ptr, __int16 value, __int16 comparand );
     __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchadd2 (volatile void *ptr, __int16 addend );
     __int16 __TBB_EXPORTED_FUNC __TBB_machine_fetchstore2 (volatile void *ptr, __int16 value );
-    void __TBB_EXPORTED_FUNC __TBB_machine_pause (__int32 delay );
 }
 
 inline long __TBB_machine_cmpswp4 (volatile void *ptr, __int32 value, __int32 comparand ) {
@@ -95,29 +87,10 @@ inline __int64 __TBB_machine_fetchstore8 (volatile void *ptr, __int64 value ) {
     return _InterlockedExchange64( (__int64*)ptr, value );
 }
 
-#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE   1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
-
-#if !__INTEL_COMPILER
-extern "C" unsigned char _BitScanReverse64( unsigned long* i, unsigned __int64 w );
-#pragma intrinsic(_BitScanReverse64)
-#endif
-
-inline __int64 __TBB_machine_lg( unsigned __int64 i ) {
-#if __INTEL_COMPILER
-    unsigned __int64 j;
-    __asm
-    {
-        bsr rax, i
-        mov j, rax
-    }
-#else
-    unsigned long j;
-    _BitScanReverse64( &j, i );
-#endif
-    return j;
-}
+#define __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE           1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 inline void __TBB_machine_OR( volatile void *operand, intptr_t addend ) {
     _InterlockedOr64((__int64*)operand, addend); 
@@ -130,20 +103,3 @@ inline void __TBB_machine_AND( volatile void *operand, intptr_t addend ) {
 #define __TBB_AtomicOR(P,V) __TBB_machine_OR(P,V)
 #define __TBB_AtomicAND(P,V) __TBB_machine_AND(P,V)
 
-extern "C" __declspec(dllimport) int __stdcall SwitchToThread( void );
-#define __TBB_Yield()  SwitchToThread()
-#define __TBB_Pause(V) __TBB_machine_pause(V)
-#define __TBB_Log2(V)  __TBB_machine_lg(V)
-
-// API to retrieve/update FPU control setting
-#define __TBB_CPU_CTL_ENV_PRESENT 1
-
-struct __TBB_cpu_ctl_env_t {
-    int     mxcsr;
-    short   x87cw;
-};
-
-extern "C" {
-    void __TBB_EXPORTED_FUNC __TBB_get_cpu_ctl_env ( __TBB_cpu_ctl_env_t* );
-    void __TBB_EXPORTED_FUNC __TBB_set_cpu_ctl_env ( const __TBB_cpu_ctl_env_t* );
-}
index 382b4efc3a3f2e793e31b00142f8625b46e11565..148e5b1d0c990e914031aab2b5e3471aea3d3a1a 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 // TODO: revise by comparing with mac_ppc.h
@@ -50,7 +42,7 @@ extern "C" void _MemoryBarrier();
 #define __TBB_full_memory_fence() __sync()
 
 #define __TBB_WORDSIZE 4
-#define __TBB_BIG_ENDIAN 1
+#define __TBB_ENDIANNESS __TBB_ENDIAN_BIG
 
 //todo: define __TBB_USE_FENCED_ATOMICS and define acquire/release primitives to maximize performance
 
@@ -69,12 +61,13 @@ inline __int64 __TBB_machine_cmpswp8(volatile void *ptr, __int64 value, __int64
  return result;
 }
 
-#define __TBB_USE_GENERIC_PART_WORD_CAS             1
-#define __TBB_USE_GENERIC_FETCH_ADD                 1
-#define __TBB_USE_GENERIC_FETCH_STORE               1
-#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE    1
-#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE        1
-#define __TBB_USE_GENERIC_DWORD_LOAD_STORE          1
+#define __TBB_USE_GENERIC_PART_WORD_CAS                     1
+#define __TBB_USE_GENERIC_FETCH_ADD                         1
+#define __TBB_USE_GENERIC_FETCH_STORE                       1
+#define __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE            1
+#define __TBB_USE_GENERIC_RELAXED_LOAD_STORE                1
+#define __TBB_USE_GENERIC_DWORD_LOAD_STORE                  1
+#define __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE 1
 
 #pragma optimize( "", off )
 inline void __TBB_machine_pause (__int32 delay ) 
index 980a8bfb69497897dbcee34b4f1a8d7daa2b80b3..47b8e1b2c5e53bf8edcb8c459d50e16342d7ca3b 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_memory_pool_H
 /** @file */
 
 #include "scalable_allocator.h"
-#include "tbb_stddef.h"
-#include "tbb_machine.h" // TODO: Itanium requires linkage with TBB library
 #include <new> // std::bad_alloc
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+#include <utility> // std::forward
+#endif
 
 #if __TBB_EXTRA_DEBUG
 #define __TBBMALLOC_ASSERT ASSERT
@@ -133,7 +126,16 @@ public:
         return (max > 0 ? max : 1);
     }
     //! Copy-construct value at location pointed to by p.
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+    template<typename U, typename... Args>
+    void construct(U *p, Args&&... args)
+        { ::new((void *)p) U(std::forward<Args>(args)...); }
+#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));}
+#endif
     void construct( pointer p, const value_type& value ) { ::new((void*)(p)) value_type(value); }
+#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
 
     //! Destroy value at location pointed to by p.
     void destroy( pointer p ) { p->~value_type(); }
@@ -211,12 +213,10 @@ public:
 
 template <typename Alloc>
 memory_pool<Alloc>::memory_pool(const Alloc &src) : my_alloc(src) {
-    rml::MemPoolPolicy args = {
-        allocate_request, deallocate_request, sizeof(typename Alloc::value_type)
-    };
-    my_pool = rml::pool_create(intptr_t(this), &args);
-    __TBBMALLOC_ASSERT(my_pool, "Pool is not created");
-    if( !my_pool ) __TBB_THROW(std::bad_alloc());
+    rml::MemPoolPolicy args(allocate_request, deallocate_request,
+                            sizeof(typename Alloc::value_type));
+    rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
+    if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc());
 }
 template <typename Alloc>
 void *memory_pool<Alloc>::allocate_request(intptr_t pool_id, size_t & bytes) {
@@ -228,6 +228,12 @@ void *memory_pool<Alloc>::allocate_request(intptr_t pool_id, size_t & bytes) {
     __TBB_CATCH(...) { return 0; }
     return ptr;
 }
+#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
+    // Workaround for erroneous "unreachable code" warning in the template below.
+    // Specific for VC++ 17-18 compiler
+    #pragma warning (push)
+    #pragma warning (disable: 4702)
+#endif
 template <typename Alloc>
 int memory_pool<Alloc>::deallocate_request(intptr_t pool_id, void* raw_ptr, size_t raw_bytes) {
     memory_pool<Alloc> &self = *reinterpret_cast<memory_pool<Alloc>*>(pool_id);
@@ -236,16 +242,20 @@ int memory_pool<Alloc>::deallocate_request(intptr_t pool_id, void* raw_ptr, size
     self.my_alloc.deallocate( static_cast<typename Alloc::value_type*>(raw_ptr), raw_bytes/unit_size );
     return 0;
 }
+#if __TBB_MSVC_UNREACHABLE_CODE_IGNORED
+    #pragma warning (pop)
+#endif
 inline fixed_pool::fixed_pool(void *buf, size_t size) : my_buffer(buf), my_size(size) {
-    rml::MemPoolPolicy args = { allocate_request, 0, size };
-    my_pool = rml::pool_create(intptr_t(this), &args);
-    __TBBMALLOC_ASSERT(my_pool, "Pool is not created");
-    if( !my_pool ) __TBB_THROW(std::bad_alloc());
+    if( !buf || !size ) __TBB_THROW(std::bad_alloc());
+    rml::MemPoolPolicy args(allocate_request, 0, size, /*fixedPool=*/true);
+    rml::MemPoolError res = rml::pool_create_v1(intptr_t(this), &args, &my_pool);
+    if( res!=rml::POOL_OK ) __TBB_THROW(std::bad_alloc());
 }
 inline void *fixed_pool::allocate_request(intptr_t pool_id, size_t & bytes) {
     fixed_pool &self = *reinterpret_cast<fixed_pool*>(pool_id);
-    if( bytes > self.my_size || !__TBB_CompareAndSwapW(&self.my_size, 0, (bytes=self.my_size)) )
-        return 0; // all the memory was given already
+    __TBBMALLOC_ASSERT(0 != self.my_size, "The buffer must not be used twice.");
+    bytes = self.my_size;
+    self.my_size = 0; // remember that buffer has been used
     return self.my_buffer;
 }
 
index b45e67d7647a43f7bcb66903017bd058e466b7b8..32340f8b1376099ba292c345285c49e8c9e2d6af 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_mutex_H
@@ -45,7 +37,7 @@ namespace tbb {
 //! Wrapper around the platform's native reader-writer lock.
 /** For testing purposes only.
     @ingroup synchronization */
-class mutex {
+class mutex : internal::mutex_copy_deprecated_and_disabled {
 public:
     //! Construct unacquired mutex.
     mutex() {
@@ -53,7 +45,7 @@ public:
     internal_construct();
 #else
   #if _WIN32||_WIN64
-        InitializeCriticalSection(&impl);
+        InitializeCriticalSectionEx(&impl, 4000, 0);
   #else
         int error_code = pthread_mutex_init(&impl,NULL);
         if( error_code )
@@ -155,13 +147,15 @@ public:
     //! Acquire lock
     void lock() {
 #if TBB_USE_ASSERT
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         new(tmp.begin()) scoped_lock(*this);
 #else
   #if _WIN32||_WIN64
         EnterCriticalSection(&impl);
   #else
-        pthread_mutex_lock(&impl);
+        int error_code = pthread_mutex_lock(&impl);
+        if( error_code )
+            tbb::internal::handle_perror(error_code,"mutex: pthread_mutex_lock failed");
   #endif /* _WIN32||_WIN64 */
 #endif /* TBB_USE_ASSERT */
     }
@@ -170,7 +164,7 @@ public:
     /** Return true if lock acquired; false otherwise. */
     bool try_lock() {
 #if TBB_USE_ASSERT
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         scoped_lock& s = *tmp.begin();
         s.my_mutex = NULL;
         return s.internal_try_acquire(*this);
@@ -186,7 +180,7 @@ public:
     //! Release lock
     void unlock() {
 #if TBB_USE_ASSERT
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         scoped_lock& s = *tmp.begin();
         s.my_mutex = this;
         s.internal_release();
index b233b4b1c05595c2de038a55c7f9f854ae7a8c99..240e9bdcc9dee24e6db5d8156bda0829d1a3603e 100644 (file)
@@ -1,46 +1,37 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_null_mutex_H
 #define __TBB_null_mutex_H
 
+#include "tbb_stddef.h"
+
 namespace tbb {
     
 //! A mutex which does nothing
 /** A null_mutex does no operation and simulates success.
     @ingroup synchronization */
-class null_mutex {   
-    //! Deny assignment and copy construction 
-    null_mutex( const null_mutex& );   
-    void operator=( const null_mutex& );   
+class null_mutex : internal::mutex_copy_deprecated_and_disabled {
 public:   
     //! Represents acquisition of a mutex.
-    class scoped_lock {   
+    class scoped_lock : internal::no_copy {   
     public:   
         scoped_lock() {}
         scoped_lock( null_mutex& ) {}   
index d7e51cf2859ce5aacfba96f36965299aca2ab836..813f79f39f532e062a8cae7fb1a37a652b8157c6 100644 (file)
@@ -1,46 +1,37 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_null_rw_mutex_H
 #define __TBB_null_rw_mutex_H
 
+#include "tbb_stddef.h"
+
 namespace tbb {
     
 //! A rw mutex which does nothing
 /** A null_rw_mutex is a rw mutex that does nothing and simulates successful operation.
     @ingroup synchronization */
-class null_rw_mutex {
-    //! Deny assignment and copy construction 
-    null_rw_mutex( const null_rw_mutex& );   
-    void operator=( const null_rw_mutex& );   
+class null_rw_mutex : internal::mutex_copy_deprecated_and_disabled {
 public:   
     //! Represents acquisition of a mutex.
-    class scoped_lock {   
+    class scoped_lock : internal::no_copy {   
     public:   
         scoped_lock() {}
         scoped_lock( null_rw_mutex& , bool = true ) {}
index f54d3b3a4d0818ea0d2e7b41b7d698afa437a28b..8173a97152c95403e599e863fd61a0b11d9f2844 100644 (file)
@@ -1,34 +1,27 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_do_H
 #define __TBB_parallel_do_H
 
+#include "internal/_range_iterator.h"
 #include "task.h"
 #include "aligned_space.h"
 #include <iterator>
@@ -489,6 +482,16 @@ void parallel_do( Iterator first, Iterator last, const Body& body )
         );
 }
 
+template<typename Range, typename Body>
+void parallel_do(Range& rng, const Body& body) {
+    parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body);
+}
+
+template<typename Range, typename Body>
+void parallel_do(const Range& rng, const Body& body) {
+    parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body);
+}
+
 #if __TBB_TASK_GROUP_CONTEXT
 //! Parallel iteration over a range, with optional addition of more work and user-supplied context
 /** @ingroup algorithms */
@@ -499,6 +502,17 @@ void parallel_do( Iterator first, Iterator last, const Body& body, task_group_co
         return;
     internal::select_parallel_do( first, last, body, &Body::operator(), context );
 }
+
+template<typename Range, typename Body>
+void parallel_do(Range& rng, const Body& body, task_group_context& context) {
+    parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context);
+}
+
+template<typename Range, typename Body>
+void parallel_do(const Range& rng, const Body& body, task_group_context& context) {
+    parallel_do(tbb::internal::first(rng), tbb::internal::last(rng), body, context);
+}
+
 #endif // __TBB_TASK_GROUP_CONTEXT
 
 //@}
index 5b998fd3e89f9d8b17ff80612a779aa87c47b4d5..4dc499cf04755152bce06c63728bc27d385b14ab 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_for_H
 
 namespace tbb {
 
-namespace interface6 {
+namespace interface7 {
 //! @cond INTERNAL
 namespace internal {
 
+    //! allocate right task with new parent
+    void* allocate_sibling(task* start_for_task, size_t bytes);
+
     //! Task type used in parallel_for
     /** @ingroup algorithms */
     template<typename Range, typename Body, typename Partitioner>
@@ -50,20 +45,25 @@ namespace internal {
         typename Partitioner::task_partition_type my_partition;
         /*override*/ task* execute();
 
+        //! Update affinity info, if any.
+        /*override*/ void note_affinity( affinity_id id ) {
+            my_partition.note_affinity( id );
+        }
+
     public:
         //! Constructor for root task.
         start_for( const Range& range, const Body& body, Partitioner& partitioner ) :
-            my_range(range),    
+            my_range(range),
             my_body(body),
             my_partition(partitioner)
         {
         }
         //! Splitting constructor used to generate children.
         /** parent_ becomes left child.  Newly constructed object is right child. */
-        start_for( start_for& parent_, split ) :
-            my_range(parent_.my_range,split()),
+        start_for( start_for& parent_, typename Partitioner::split_type& split_obj) :
+            my_range(parent_.my_range, split_obj),
             my_body(parent_.my_body),
-            my_partition(parent_.my_partition, split())
+            my_partition(parent_.my_partition, split_obj)
         {
             my_partition.set_affinity(*this);
         }
@@ -72,71 +72,95 @@ namespace internal {
         start_for( start_for& parent_, const Range& r, depth_t d ) :
             my_range(r),
             my_body(parent_.my_body),
-            my_partition(parent_.my_partition,split())
+            my_partition(parent_.my_partition, split())
         {
             my_partition.set_affinity(*this);
             my_partition.align_depth( d );
         }
-        //! Update affinity info, if any.
-        /*override*/ void note_affinity( affinity_id id ) {
-            my_partition.note_affinity( id );
-        }
-        static void run(  const Range& range, const Body& body, const Partitioner& partitioner ) {
+        static void run(  const Range& range, const Body& body, Partitioner& partitioner ) {
             if( !range.empty() ) {
 #if !__TBB_TASK_GROUP_CONTEXT || TBB_JOIN_OUTER_TASK_GROUP
-                start_for& a = *new(task::allocate_root()) start_for(range,body,const_cast<Partitioner&>(partitioner));
+                start_for& a = *new(task::allocate_root()) start_for(range,body,partitioner);
 #else
                 // Bound context prevents exceptions from body to affect nesting or sibling algorithms,
                 // and allows users to handle exceptions safely by wrapping parallel_for in the try-block.
                 task_group_context context;
-                start_for& a = *new(task::allocate_root(context)) start_for(range,body,const_cast<Partitioner&>(partitioner));
+                start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner);
 #endif /* __TBB_TASK_GROUP_CONTEXT && !TBB_JOIN_OUTER_TASK_GROUP */
                 task::spawn_root_and_wait(a);
             }
         }
 #if __TBB_TASK_GROUP_CONTEXT
-        static void run(  const Range& range, const Body& body, const Partitioner& partitioner, task_group_context& context ) {
+        static void run(  const Range& range, const Body& body, Partitioner& partitioner, task_group_context& context ) {
             if( !range.empty() ) {
-                start_for& a = *new(task::allocate_root(context)) start_for(range,body,const_cast<Partitioner&>(partitioner));
+                start_for& a = *new(task::allocate_root(context)) start_for(range,body,partitioner);
                 task::spawn_root_and_wait(a);
             }
         }
 #endif /* __TBB_TASK_GROUP_CONTEXT */
-        //! create a continuation task, serve as callback for partitioner
-        flag_task *create_continuation() {
-            return new( allocate_continuation() ) flag_task();
-        }
-        //! Run body for range
+        //! Run body for range, serves as callback for partitioner
         void run_body( Range &r ) { my_body( r ); }
+
+        //! spawn right task, serves as callback for partitioner
+        void offer_work(typename Partitioner::split_type& split_obj) {
+            spawn( *new( allocate_sibling(static_cast<task*>(this), sizeof(start_for)) ) start_for(*this, split_obj) );
+        }
+        //! spawn right task, serves as callback for partitioner
+        void offer_work(const Range& r, depth_t d = 0) {
+            spawn( *new( allocate_sibling(static_cast<task*>(this), sizeof(start_for)) ) start_for(*this, r, d) );
+        }
     };
 
+    //! allocate right task with new parent
+    // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined
+    inline void* allocate_sibling(task* start_for_task, size_t bytes) {
+        task* parent_ptr = new( start_for_task->allocate_continuation() ) flag_task();
+        start_for_task->set_parent(parent_ptr);
+        parent_ptr->set_ref_count(2);
+        return &parent_ptr->allocate_child().allocate(bytes);
+    }
+
+    //! execute task for parallel_for
     template<typename Range, typename Body, typename Partitioner>
     task* start_for<Range,Body,Partitioner>::execute() {
         my_partition.check_being_stolen( *this );
         my_partition.execute(*this, my_range);
         return NULL;
-    } 
+    }
 } // namespace internal
 //! @endcond
 } // namespace interfaceX
 
 //! @cond INTERNAL
 namespace internal {
-    using interface6::internal::start_for;
-    
+    using interface7::internal::start_for;
+
     //! Calls the function with values from range [begin, end) with a step provided
     template<typename Function, typename Index>
     class parallel_for_body : internal::no_assign {
         const Function &my_func;
         const Index my_begin;
-        const Index my_step; 
+        const Index my_step;
     public:
-        parallel_for_body( const Function& _func, Index& _begin, Index& _step
+        parallel_for_body( const Function& _func, Index& _begin, Index& _step )
             : my_func(_func), my_begin(_begin), my_step(_step) {}
-        
-        void operator()( tbb::blocked_range<Index>& r ) const {
-            for( Index i = r.begin(),  k = my_begin + i * my_step; i < r.end(); i++, k = k + my_step)
+
+        void operator()( const tbb::blocked_range<Index>& r ) const {
+            // A set of local variables to help the compiler with vectorization of the following loop.
+            Index b = r.begin();
+            Index e = r.end();
+            Index ms = my_step;
+            Index k = my_begin + b*ms;
+
+#if __INTEL_COMPILER
+#pragma ivdep
+#if __TBB_ASSERT_ON_VECTORIZATION_FAILURE
+#pragma vector always assert
+#endif
+#endif
+            for ( Index i = b; i < e; ++i, k += ms ) {
                 my_func( k );
+            }
         }
     };
 } // namespace internal
@@ -155,25 +179,25 @@ namespace internal {
     See also requirements on \ref range_req "Range" and \ref parallel_for_body_req "parallel_for Body". **/
 //@{
 
-//! Parallel iteration over range with default partitioner. 
+//! Parallel iteration over range with default partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body ) {
-    internal::start_for<Range,Body,__TBB_DEFAULT_PARTITIONER>::run(range,body,__TBB_DEFAULT_PARTITIONER());
+    internal::start_for<Range,Body,const __TBB_DEFAULT_PARTITIONER>::run(range,body,__TBB_DEFAULT_PARTITIONER());
 }
 
 //! Parallel iteration over range with simple partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner ) {
-    internal::start_for<Range,Body,simple_partitioner>::run(range,body,partitioner);
+    internal::start_for<Range,Body,const simple_partitioner>::run(range,body,partitioner);
 }
 
 //! Parallel iteration over range with auto_partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner ) {
-    internal::start_for<Range,Body,auto_partitioner>::run(range,body,partitioner);
+    internal::start_for<Range,Body,const auto_partitioner>::run(range,body,partitioner);
 }
 
 //! Parallel iteration over range with affinity_partitioner.
@@ -184,18 +208,25 @@ void parallel_for( const Range& range, const Body& body, affinity_partitioner& p
 }
 
 #if __TBB_TASK_GROUP_CONTEXT
+//! Parallel iteration over range with default partitioner and user-supplied context.
+/** @ingroup algorithms **/
+template<typename Range, typename Body>
+void parallel_for( const Range& range, const Body& body, task_group_context& context ) {
+    internal::start_for<Range,Body,const __TBB_DEFAULT_PARTITIONER>::run(range, body, __TBB_DEFAULT_PARTITIONER(), context);
+}
+
 //! Parallel iteration over range with simple partitioner and user-supplied context.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, const simple_partitioner& partitioner, task_group_context& context ) {
-    internal::start_for<Range,Body,simple_partitioner>::run(range, body, partitioner, context);
+    internal::start_for<Range,Body,const simple_partitioner>::run(range, body, partitioner, context);
 }
 
 //! Parallel iteration over range with auto_partitioner and user-supplied context.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
 void parallel_for( const Range& range, const Body& body, const auto_partitioner& partitioner, task_group_context& context ) {
-    internal::start_for<Range,Body,auto_partitioner>::run(range, body, partitioner, context);
+    internal::start_for<Range,Body,const auto_partitioner>::run(range, body, partitioner, context);
 }
 
 //! Parallel iteration over range with affinity_partitioner and user-supplied context.
@@ -210,9 +241,9 @@ void parallel_for( const Range& range, const Body& body, affinity_partitioner& p
 namespace strict_ppl {
 
 //@{
-//! Parallel iteration over a range of integers with a step provided
-template <typename Index, typename Function>
-void parallel_for(Index first, Index last, Index step, const Function& f) {
+//! Implementation of parallel iteration over stepped range of integers with explicit step and partitioner
+template <typename Index, typename Function, typename Partitioner>
+void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner) {
     if (step <= 0 )
         internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument
     else if (last > first) {
@@ -220,19 +251,56 @@ void parallel_for(Index first, Index last, Index step, const Function& f) {
         Index end = (last - first - Index(1)) / step + Index(1);
         tbb::blocked_range<Index> range(static_cast<Index>(0), end);
         internal::parallel_for_body<Function, Index> body(f, first, step);
-        tbb::parallel_for(range, body, tbb::auto_partitioner());
+        tbb::parallel_for(range, body, partitioner);
     }
 }
-//! Parallel iteration over a range of integers with a default step value
+
+//! Parallel iteration over a range of integers with a step provided and default partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, auto_partitioner());
+}
+//! Parallel iteration over a range of integers with a step provided and simple partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner) {
+    parallel_for_impl<Index,Function,const simple_partitioner>(first, last, step, f, partitioner);
+}
+//! Parallel iteration over a range of integers with a step provided and auto partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, partitioner);
+}
+//! Parallel iteration over a range of integers with a step provided and affinity partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner) {
+    parallel_for_impl(first, last, step, f, partitioner);
+}
+
+//! Parallel iteration over a range of integers with a default step value and default partitioner
 template <typename Index, typename Function>
 void parallel_for(Index first, Index last, const Function& f) {
-    parallel_for(first, last, static_cast<Index>(1), f);
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, auto_partitioner());
+}
+//! Parallel iteration over a range of integers with a default step value and simple partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner) {
+    parallel_for_impl<Index,Function,const simple_partitioner>(first, last, static_cast<Index>(1), f, partitioner);
+}
+//! Parallel iteration over a range of integers with a default step value and auto partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, partitioner);
+}
+//! Parallel iteration over a range of integers with a default step value and affinity partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner) {
+    parallel_for_impl(first, last, static_cast<Index>(1), f, partitioner);
 }
 
 #if __TBB_TASK_GROUP_CONTEXT
-//! Parallel iteration over a range of integers with explicit step and task group context
-template <typename Index, typename Function>
-void parallel_for(Index first, Index last, Index step, const Function& f, tbb::task_group_context &context) {
+//! Implementation of parallel iteration over stepped range of integers with explicit step, task group context, and partitioner
+template <typename Index, typename Function, typename Partitioner>
+void parallel_for_impl(Index first, Index last, Index step, const Function& f, Partitioner& partitioner, tbb::task_group_context &context) {
     if (step <= 0 )
         internal::throw_exception(internal::eid_nonpositive_step); // throws std::invalid_argument
     else if (last > first) {
@@ -240,14 +308,53 @@ void parallel_for(Index first, Index last, Index step, const Function& f, tbb::t
         Index end = (last - first - Index(1)) / step + Index(1);
         tbb::blocked_range<Index> range(static_cast<Index>(0), end);
         internal::parallel_for_body<Function, Index> body(f, first, step);
-        tbb::parallel_for(range, body, tbb::auto_partitioner(), context);
+        tbb::parallel_for(range, body, partitioner, context);
     }
 }
-//! Parallel iteration over a range of integers with a default step value and explicit task group context
+
+//! Parallel iteration over a range of integers with explicit step, task group context, and default partitioner
+template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, tbb::task_group_context &context) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, auto_partitioner(), context);
+}
+//! Parallel iteration over a range of integers with explicit step, task group context, and simple partitioner
+ template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) {
+    parallel_for_impl<Index,Function,const simple_partitioner>(first, last, step, f, partitioner, context);
+}
+//! Parallel iteration over a range of integers with explicit step, task group context, and auto partitioner
+ template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, step, f, partitioner, context);
+}
+//! Parallel iteration over a range of integers with explicit step, task group context, and affinity partitioner
+ template <typename Index, typename Function>
+void parallel_for(Index first, Index last, Index step, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) {
+    parallel_for_impl(first, last, step, f, partitioner, context);
+}
+
+
+//! Parallel iteration over a range of integers with a default step value, explicit task group context, and default partitioner
 template <typename Index, typename Function>
 void parallel_for(Index first, Index last, const Function& f, tbb::task_group_context &context) {
-    parallel_for(first, last, static_cast<Index>(1), f, context);
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, auto_partitioner(), context);
+}
+//! Parallel iteration over a range of integers with a default step value, explicit task group context, and simple partitioner
+ template <typename Index, typename Function, typename Partitioner>
+void parallel_for(Index first, Index last, const Function& f, const simple_partitioner& partitioner, tbb::task_group_context &context) {
+    parallel_for_impl<Index,Function,const simple_partitioner>(first, last, static_cast<Index>(1), f, partitioner, context);
+}
+//! Parallel iteration over a range of integers with a default step value, explicit task group context, and auto partitioner
+ template <typename Index, typename Function, typename Partitioner>
+void parallel_for(Index first, Index last, const Function& f, const auto_partitioner& partitioner, tbb::task_group_context &context) {
+    parallel_for_impl<Index,Function,const auto_partitioner>(first, last, static_cast<Index>(1), f, partitioner, context);
 }
+//! Parallel iteration over a range of integers with a default step value, explicit task group context, and affinity_partitioner
+ template <typename Index, typename Function, typename Partitioner>
+void parallel_for(Index first, Index last, const Function& f, affinity_partitioner& partitioner, tbb::task_group_context &context) {
+    parallel_for_impl(first, last, static_cast<Index>(1), f, partitioner, context);
+}
+
 #endif /* __TBB_TASK_GROUP_CONTEXT */
 //@}
 
@@ -264,4 +371,3 @@ using strict_ppl::parallel_for;
 #endif
 
 #endif /* __TBB_parallel_for_H */
-
index 59200b1ebb1d33d8395abb817f3f7428a26b8aed..c7dc39f4dbdfaca31799700d5d6766e8d9e75691 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_for_each_H
@@ -61,6 +53,20 @@ void parallel_for_each(InputIterator first, InputIterator last, const Function&
     internal::parallel_for_each_body<Function, InputIterator> body(f);
     tbb::parallel_do (first, last, body, context);
 }
+
+//! Calls function f for all items from rng using user-supplied context
+/** @ingroup algorithms */
+template<typename Range, typename Function>
+void parallel_for_each(Range& rng, const Function& f, task_group_context& context) {
+    parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context);
+}
+
+//! Calls function f for all items from const rng user-supplied context
+/** @ingroup algorithms */
+template<typename Range, typename Function>
+void parallel_for_each(const Range& rng, const Function& f, task_group_context& context) {
+    parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f, context);
+}
 #endif /* __TBB_TASK_GROUP_CONTEXT */
 
 //! Uses default context
@@ -70,6 +76,18 @@ void parallel_for_each(InputIterator first, InputIterator last, const Function&
     tbb::parallel_do (first, last, body);
 }
 
+//! Uses default context
+template<typename Range, typename Function>
+void parallel_for_each(Range& rng, const Function& f) {
+    parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f);
+}
+
+//! Uses default context
+template<typename Range, typename Function>
+void parallel_for_each(const Range& rng, const Function& f) {
+    parallel_for_each(tbb::internal::first(rng), tbb::internal::last(rng), f);
+}
+
 //@}
 
 } // namespace
index 6cc38e26534ff1a4ef4087e174887b290faeecb4..bc055850af3efadcf940af6dca968a28da2e23b6 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_invoke_H
 
 #include "task.h"
 
+#if __TBB_VARIADIC_PARALLEL_INVOKE
+    #include <utility>
+#endif
+
 namespace tbb {
 
 #if !__TBB_TASK_GROUP_CONTEXT
@@ -103,9 +99,40 @@ namespace internal {
         {
             set_ref_count(number_of_children + 1);
         }
+
+#if __TBB_VARIADIC_PARALLEL_INVOKE
+        void add_children() {}
+        void add_children(tbb::task_group_context&) {}
+
+        template <typename function>
+        void add_children(function&& _func)
+        {
+            internal::function_invoker<function>* invoker = new (allocate_child()) internal::function_invoker<function>(std::forward<function>(_func));
+            __TBB_ASSERT(invoker, "Child task allocation failed");
+            spawn(*invoker);
+        }
+
+        template<typename function>
+        void add_children(function&& _func, tbb::task_group_context&)
+        {
+            add_children(std::forward<function>(_func));
+        }
+
+        // Adds child(ren) task(s) and spawns them
+        template <typename function1, typename function2, typename... function>
+        void add_children(function1&& _func1, function2&& _func2, function&&... _func)
+        {
+            // The third argument is dummy, it is ignored actually.
+            parallel_invoke_noop noop;
+            typedef internal::spawner<2, function1, function2, parallel_invoke_noop> spawner_type;
+            spawner_type & sub_root = *new(allocate_child()) spawner_type(std::forward<function1>(_func1), std::forward<function2>(_func2), noop);
+            spawn(sub_root);
+            add_children(std::forward<function>(_func)...);
+        }
+#else
         // Adds child task and spawns it
         template <typename function>
-        void add_child (const function &_func)
+        void add_children (const function &_func)
         {
             internal::function_invoker<function>* invoker = new (allocate_child()) internal::function_invoker<function>(_func);
             __TBB_ASSERT(invoker, "Child task allocation failed");
@@ -129,6 +156,7 @@ namespace internal {
             internal::spawner<3, function1, function2, function3>& sub_root = *new(allocate_child())internal::spawner<3, function1, function2, function3>(_func1, _func2, _func3);
             spawn(sub_root);
         }
+#endif // __TBB_VARIADIC_PARALLEL_INVOKE
 
         // Waits for all child tasks
         template <typename F0>
@@ -139,8 +167,8 @@ namespace internal {
             spawn_and_wait_for_all(*invoker);
         }
     };
-    // The class destroys root if exception occured as well as in normal case
-    class parallel_invoke_cleaner: internal::no_copy { 
+    // The class destroys root if exception occurred as well as in normal case
+    class parallel_invoke_cleaner: internal::no_copy {
     public:
 #if __TBB_TASK_GROUP_CONTEXT
         parallel_invoke_cleaner(int number_of_children, tbb::task_group_context& context)
@@ -156,6 +184,51 @@ namespace internal {
         }
         internal::parallel_invoke_helper& root;
     };
+
+#if __TBB_VARIADIC_PARALLEL_INVOKE
+//  Determine whether the last parameter in a pack is task_group_context
+    template<typename... T> struct impl_selector; // to workaround a GCC bug
+
+    template<typename T1, typename... T> struct impl_selector<T1, T...> {
+        typedef typename impl_selector<T...>::type type;
+    };
+
+    template<typename T> struct impl_selector<T> {
+        typedef false_type type;
+    };
+    template<> struct impl_selector<task_group_context&> {
+        typedef true_type  type;
+    };
+
+    // Select task_group_context parameter from the back of a pack
+    inline task_group_context& get_context( task_group_context& tgc ) { return tgc; }
+
+    template<typename T1, typename... T>
+    task_group_context& get_context( T1&& /*ignored*/, T&&... t )
+    { return get_context( std::forward<T>(t)... ); }
+
+    // task_group_context is known to be at the back of the parameter pack
+    template<typename F0, typename F1, typename... F>
+    void parallel_invoke_impl(true_type, F0&& f0, F1&& f1, F&&... f) {
+        __TBB_STATIC_ASSERT(sizeof...(F)>0, "Variadic parallel_invoke implementation broken?");
+        // # of child tasks: f0, f1, and a task for each two elements of the pack except the last
+        const size_t number_of_children = 2 + sizeof...(F)/2;
+        parallel_invoke_cleaner cleaner(number_of_children, get_context(std::forward<F>(f)...));
+        parallel_invoke_helper& root = cleaner.root;
+
+        root.add_children(std::forward<F>(f)...);
+        root.add_children(std::forward<F1>(f1));
+        root.run_and_finish(std::forward<F0>(f0));
+    }
+
+    // task_group_context is not in the pack, needs to be added
+    template<typename F0, typename F1, typename... F>
+    void parallel_invoke_impl(false_type, F0&& f0, F1&& f1, F&&... f) {
+        tbb::task_group_context context;
+        // Add context to the arguments, and redirect to the other overload
+        parallel_invoke_impl(true_type(), std::forward<F0>(f0), std::forward<F1>(f1), std::forward<F>(f)..., context);
+    }
+#endif
 } // namespace internal
 //! @endcond
 
@@ -165,6 +238,18 @@ namespace internal {
 //! Executes a list of tasks in parallel and waits for all tasks to complete.
 /** @ingroup algorithms */
 
+#if __TBB_VARIADIC_PARALLEL_INVOKE
+
+// parallel_invoke for two or more arguments via variadic templates
+// presence of task_group_context is defined automatically
+template<typename F0, typename F1, typename... F>
+void parallel_invoke(F0&& f0, F1&& f1, F&&... f) {
+    typedef typename internal::impl_selector<internal::false_type, F...>::type selector_type;
+    internal::parallel_invoke_impl(selector_type(), std::forward<F0>(f0), std::forward<F1>(f1), std::forward<F>(f)...);
+}
+
+#else
+
 // parallel_invoke with user-defined context
 // two arguments
 template<typename F0, typename F1 >
@@ -172,7 +257,7 @@ void parallel_invoke(const F0& f0, const F1& f1, tbb::task_group_context& contex
     internal::parallel_invoke_cleaner cleaner(2, context);
     internal::parallel_invoke_helper& root = cleaner.root;
 
-    root.add_child(f1);
+    root.add_children(f1);
 
     root.run_and_finish(f0);
 }
@@ -183,8 +268,8 @@ void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, tbb::task_group_c
     internal::parallel_invoke_cleaner cleaner(3, context);
     internal::parallel_invoke_helper& root = cleaner.root;
 
-    root.add_child(f2);
-    root.add_child(f1);
+    root.add_children(f2);
+    root.add_children(f1);
 
     root.run_and_finish(f0);
 }
@@ -197,9 +282,9 @@ void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3,
     internal::parallel_invoke_cleaner cleaner(4, context);
     internal::parallel_invoke_helper& root = cleaner.root;
 
-    root.add_child(f3);
-    root.add_child(f2);
-    root.add_child(f1);
+    root.add_children(f3);
+    root.add_children(f2);
+    root.add_children(f1);
 
     root.run_and_finish(f0);
 }
@@ -336,8 +421,8 @@ void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, con
     task_group_context context;
     parallel_invoke<F0, F1, F2, F3, F4, F5, F6>(f0, f1, f2, f3, f4, f5, f6, context);
 }
-// eigth arguments
-template<typename F0, typename F1, typename F2, typename F3, typename F4, 
+// eight arguments
+template<typename F0, typename F1, typename F2, typename F3, typename F4,
          typename F5, typename F6, typename F7>
 void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, const F4& f4,
                      const F5& f5, const F6& f6, const F7& f7)
@@ -363,7 +448,7 @@ void parallel_invoke(const F0& f0, const F1& f1, const F2& f2, const F3& f3, con
     task_group_context context;
     parallel_invoke<F0, F1, F2, F3, F4, F5, F6, F7, F8, F9>(f0, f1, f2, f3, f4, f5, f6, f7, f8, f9, context);
 }
-
+#endif // __TBB_VARIADIC_PARALLEL_INVOKE
 //@}
 
 } // namespace
index 12d17ca0a280cada62f61263b4c6d80e119549b7..17fba20199a7810067aa6ea1c5da5b2d0248419f 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_reduce_H
 
 namespace tbb {
 
-namespace interface6 {
+namespace interface7 {
 //! @cond INTERNAL
 namespace internal {
 
     using namespace tbb::internal;
 
-    //! 0 if root, 1 if a left child, 2 if a right child.
+    /** Values for reduction_context. */
+    enum {
+        root_task, left_child, right_child
+    };
+
     /** Represented as a char, not enum, for compactness. */
     typedef char reduction_context;
 
-    //! Task type use to combine the partial results of parallel_reduce.
+    //! Task type used to combine the partial results of parallel_reduce.
     /** @ingroup algorithms */
     template<typename Body>
     class finish_reduce: public flag_task {
-        //! Pointer to body, or NULL if the left child has not yet finished. 
+        //! Pointer to body, or NULL if the left child has not yet finished.
         bool has_right_zombie;
         const reduction_context my_context;
         Body* my_body;
-        aligned_space<Body,1> zombie_space;
-        finish_reduce( reduction_context context_ ) : 
+        aligned_space<Body> zombie_space;
+        finish_reduce( reduction_context context_ ) :
             has_right_zombie(false), // TODO: substitute by flag_task::child_stolen?
             my_context(context_),
             my_body(NULL)
         {
         }
+        ~finish_reduce() {
+            if( has_right_zombie )
+                zombie_space.begin()->~Body();
+        }
         task* execute() {
             if( has_right_zombie ) {
                 // Right child was stolen.
                 Body* s = zombie_space.begin();
                 my_body->join( *s );
-                s->~Body();
+                // Body::join() won't be called if canceled. Defer destruction to destructor
             }
-            if( my_context==1 )  // left child
+            if( my_context==left_child )
                 itt_store_word_with_release( static_cast<finish_reduce*>(parent())->my_body, my_body );
             return NULL;
         }
@@ -77,6 +77,9 @@ namespace internal {
         friend class start_reduce;
     };
 
+    //! allocate right task with new parent
+    void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes);
+
     //! Task type used to split the work of parallel_reduce.
     /** @ingroup algorithms */
     template<typename Range, typename Body, typename Partitioner>
@@ -85,46 +88,46 @@ namespace internal {
         Body* my_body;
         Range my_range;
         typename Partitioner::task_partition_type my_partition;
-        reduction_context my_context; // TODO: factor out into start_reduce_base
+        reduction_context my_context;
         /*override*/ task* execute();
+        //! Update affinity info, if any
+        /*override*/ void note_affinity( affinity_id id ) {
+            my_partition.note_affinity( id );
+        }
         template<typename Body_>
         friend class finish_reduce;
-    
+
 public:
         //! Constructor used for root task
         start_reduce( const Range& range, Body* body, Partitioner& partitioner ) :
             my_body(body),
             my_range(range),
             my_partition(partitioner),
-            my_context(0)
+            my_context(root_task)
         {
         }
         //! Splitting constructor used to generate children.
         /** parent_ becomes left child.  Newly constructed object is right child. */
-        start_reduce( start_reduce& parent_, split ) :
+        start_reduce( start_reduce& parent_, typename Partitioner::split_type& split_obj ) :
             my_body(parent_.my_body),
-            my_range(parent_.my_range,split()),
-            my_partition(parent_.my_partition,split()),
-            my_context(2)
+            my_range(parent_.my_range, split_obj),
+            my_partition(parent_.my_partition, split_obj),
+            my_context(right_child)
         {
             my_partition.set_affinity(*this);
-            parent_.my_context = 1;
+            parent_.my_context = left_child;
         }
         //! Construct right child from the given range as response to the demand.
         /** parent_ remains left child.  Newly constructed object is right child. */
         start_reduce( start_reduce& parent_, const Range& r, depth_t d ) :
             my_body(parent_.my_body),
             my_range(r),
-            my_partition(parent_.my_partition,split()),
-            my_context(2) // right leaf mark
+            my_partition(parent_.my_partition, split()),
+            my_context(right_child)
         {
             my_partition.set_affinity(*this);
-            my_partition.align_depth( d );
-            parent_.my_context = 1; // left leaf mark
-        }
-        //! Update affinity info, if any
-        /*override*/ void note_affinity( affinity_id id ) {
-            my_partition.note_affinity( id );
+            my_partition.align_depth( d ); // TODO: move into constructor of partitioner
+            parent_.my_context = left_child;
         }
         static void run( const Range& range, Body& body, Partitioner& partitioner ) {
             if( !range.empty() ) {
@@ -140,38 +143,61 @@ public:
         }
 #if __TBB_TASK_GROUP_CONTEXT
         static void run( const Range& range, Body& body, Partitioner& partitioner, task_group_context& context ) {
-            if( !range.empty() ) 
+            if( !range.empty() )
                 task::spawn_root_and_wait( *new(task::allocate_root(context)) start_reduce(range,&body,partitioner) );
         }
 #endif /* __TBB_TASK_GROUP_CONTEXT */
-        //! create a continuation task, serve as callback for partitioner
-        finish_type *create_continuation() {
-            return new( allocate_continuation() ) finish_type(my_context);
-        }
         //! Run body for range
         void run_body( Range &r ) { (*my_body)( r ); }
+
+        //! spawn right task, serves as callback for partitioner
+        // TODO: remove code duplication from 'offer_work' methods
+        void offer_work(typename Partitioner::split_type& split_obj) {
+            task *tasks[2];
+            allocate_sibling(static_cast<task*>(this), tasks, sizeof(start_reduce), sizeof(finish_type));
+            new((void*)tasks[0]) finish_type(my_context);
+            new((void*)tasks[1]) start_reduce(*this, split_obj);
+            spawn(*tasks[1]);
+        }
+        //! spawn right task, serves as callback for partitioner
+        void offer_work(const Range& r, depth_t d = 0) {
+            task *tasks[2];
+            allocate_sibling(static_cast<task*>(this), tasks, sizeof(start_reduce), sizeof(finish_type));
+            new((void*)tasks[0]) finish_type(my_context);
+            new((void*)tasks[1]) start_reduce(*this, r, d);
+            spawn(*tasks[1]);
+        }
     };
+
+    //! allocate right task with new parent
+    // TODO: 'inline' here is to avoid multiple definition error but for sake of code size this should not be inlined
+    inline void allocate_sibling(task* start_reduce_task, task *tasks[], size_t start_bytes, size_t finish_bytes) {
+        tasks[0] = &start_reduce_task->allocate_continuation().allocate(finish_bytes);
+        start_reduce_task->set_parent(tasks[0]);
+        tasks[0]->set_ref_count(2);
+        tasks[1] = &tasks[0]->allocate_child().allocate(start_bytes);
+    }
+
     template<typename Range, typename Body, typename Partitioner>
     task* start_reduce<Range,Body,Partitioner>::execute() {
         my_partition.check_being_stolen( *this );
-        if( my_context==2 ) { // right child
+        if( my_context==right_child ) {
             finish_type* parent_ptr = static_cast<finish_type*>(parent());
             if( !itt_load_word_with_acquire(parent_ptr->my_body) ) { // TODO: replace by is_stolen_task() or by parent_ptr->ref_count() == 2???
                 my_body = new( parent_ptr->zombie_space.begin() ) Body(*my_body,split());
                 parent_ptr->has_right_zombie = true;
             }
-        } else __TBB_ASSERT(my_context==0,0);// because left leaf spawns right leafs without recycling
+        } else __TBB_ASSERT(my_context==root_task,NULL);// because left leaf spawns right leafs without recycling
         my_partition.execute(*this, my_range);
-        if( my_context==1 ) {
+        if( my_context==left_child ) {
             finish_type* parent_ptr = static_cast<finish_type*>(parent());
-            __TBB_ASSERT(my_body!=parent_ptr->zombie_space.begin(),0);
+            __TBB_ASSERT(my_body!=parent_ptr->zombie_space.begin(),NULL);
             itt_store_word_with_release(parent_ptr->my_body, my_body );
         }
         return NULL;
     }
 
-#if TBB_PREVIEW_DETERMINISTIC_REDUCE
-    //! Task type use to combine the partial results of parallel_deterministic_reduce.
+    //! Task type used to combine the partial results of parallel_deterministic_reduce.
     /** @ingroup algorithms */
     template<typename Body>
     class finish_deterministic_reduce: public task {
@@ -229,7 +255,7 @@ public:
         }
 #if __TBB_TASK_GROUP_CONTEXT
         static void run( const Range& range, Body& body, task_group_context& context ) {
-            if( !range.empty() ) 
+            if( !range.empty() )
                 task::spawn_root_and_wait( *new(task::allocate_root(context)) start_deterministic_reduce(range,body) );
         }
 #endif /* __TBB_TASK_GROUP_CONTEXT */
@@ -249,17 +275,14 @@ public:
             return this;
         }
     }
-#endif /* TBB_PREVIEW_DETERMINISTIC_REDUCE */
 } // namespace internal
 //! @endcond
 } //namespace interfaceX
 
 //! @cond INTERNAL
 namespace internal {
-    using interface6::internal::start_reduce;
-#if TBB_PREVIEW_DETERMINISTIC_REDUCE
-    using interface6::internal::start_deterministic_reduce;
-#endif
+    using interface7::internal::start_reduce;
+    using interface7::internal::start_deterministic_reduce;
     //! Auxiliary class for parallel_reduce; for internal use only.
     /** The adaptor class that implements \ref parallel_reduce_body_req "parallel_reduce Body"
         using given \ref parallel_reduce_lambda_req "anonymous function objects".
@@ -318,7 +341,7 @@ namespace internal {
     - \code Body::~Body(); \endcode                     Destructor
     - \code void Body::operator()( Range& r ); \endcode Function call operator applying body to range \c r
                                                         and accumulating the result
-    - \code void Body::join( Body& b ); \endcode        Join results. 
+    - \code void Body::join( Body& b ); \endcode        Join results.
                                                         The result in \c b should be merged into the result of \c this
 **/
 
@@ -462,7 +485,6 @@ Value parallel_reduce( const Range& range, const Value& identity, const RealBody
 }
 #endif /* __TBB_TASK_GROUP_CONTEXT */
 
-#if TBB_PREVIEW_DETERMINISTIC_REDUCE
 //! Parallel iteration with deterministic reduction and default partitioner.
 /** @ingroup algorithms **/
 template<typename Range, typename Body>
@@ -504,10 +526,8 @@ Value parallel_deterministic_reduce( const Range& range, const Value& identity,
     return body.result();
 }
 #endif /* __TBB_TASK_GROUP_CONTEXT */
-#endif /* TBB_PREVIEW_DETERMINISTIC_REDUCE */
 //@}
 
 } // namespace tbb
 
 #endif /* __TBB_parallel_reduce_H */
-
index a4a02cb96e6a82667898db5a76c80eaa1d578411..e9d8c692e6fd26a4b7b6f8d8a7753fd8a330a8ad 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
 
-    This file is part of Threading Building Blocks.
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
 
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_scan_H
@@ -56,29 +48,29 @@ namespace internal {
     template<typename Range, typename Body>
     class final_sum: public task {
     public:
-        Body body;
+        Body my_body;
     private:
-        aligned_space<Range,1> range;
+        aligned_space<Range> my_range;
         //! Where to put result of last subrange, or NULL if not last subrange.
-        Body* stuff_last;
+        Body* my_stuff_last;
     public:
         final_sum( Body& body_ ) :
-            body(body_,split())
+            my_body(body_,split())
         {
-            poison_pointer(stuff_last);
+            poison_pointer(my_stuff_last);
         }
         ~final_sum() {
-            range.begin()->~Range();
+            my_range.begin()->~Range();
         }     
         void finish_construction( const Range& range_, Body* stuff_last_ ) {
-            new( range.begin() ) Range(range_);
-            stuff_last = stuff_last_;
+            new( my_range.begin() ) Range(range_);
+            my_stuff_last = stuff_last_;
         }
     private:
         /*override*/ task* execute() {
-            body( *range.begin(), final_scan_tag() );
-            if( stuff_last )
-                stuff_last->assign(body);
+            my_body( *my_range.begin(), final_scan_tag() );
+            if( my_stuff_last )
+                my_stuff_last->assign(my_body);
             return NULL;
         }
     };       
@@ -89,25 +81,25 @@ namespace internal {
     class sum_node: public task {
         typedef final_sum<Range,Body> final_sum_type;
     public:
-        final_sum_type *incoming; 
-        final_sum_type *body;
-        Body *stuff_last;
+        final_sum_type *my_incoming; 
+        final_sum_type *my_body;
+        Body *my_stuff_last;
     private:
-        final_sum_type *left_sum;
-        sum_node *left;
-        sum_node *right;     
-        bool left_is_final;
-        Range range;
+        final_sum_type *my_left_sum;
+        sum_node *my_left;
+        sum_node *my_right;     
+        bool my_left_is_final;
+        Range my_range;
         sum_node( const Range range_, bool left_is_final_ ) : 
-            left_sum(NULL), 
-            left(NULL), 
-            right(NULL), 
-            left_is_final(left_is_final_), 
-            range(range_)
+            my_left_sum(NULL), 
+            my_left(NULL), 
+            my_right(NULL), 
+            my_left_is_final(left_is_final_), 
+            my_range(range_)
         {
             // Poison fields that will be set by second pass.
-            poison_pointer(body);
-            poison_pointer(incoming);
+            poison_pointer(my_body);
+            poison_pointer(my_incoming);
         }
         task* create_child( const Range& range_, final_sum_type& f, sum_node* n, final_sum_type* incoming_, Body* stuff_last_ ) {
             if( !n ) {
@@ -115,22 +107,22 @@ namespace internal {
                 f.finish_construction( range_, stuff_last_ );
                 return &f;
             } else {
-                n->body = &f;
-                n->incoming = incoming_;
-                n->stuff_last = stuff_last_;
+                n->my_body = &f;
+                n->my_incoming = incoming_;
+                n->my_stuff_last = stuff_last_;
                 return n;
             }
         }
         /*override*/ task* execute() {
-            if( body ) {
-                if( incoming )
-                    left_sum->body.reverse_join( incoming->body );
+            if( my_body ) {
+                if( my_incoming )
+                    my_left_sum->my_body.reverse_join( my_incoming->my_body );
                 recycle_as_continuation();
                 sum_node& c = *this;
-                task* b = c.create_child(Range(range,split()),*left_sum,right,left_sum,stuff_last);
-                task* a = left_is_final ? NULL : c.create_child(range,*body,left,incoming,NULL);
+                task* b = c.create_child(Range(my_range,split()),*my_left_sum,my_right,my_left_sum,my_stuff_last);
+                task* a = my_left_is_final ? NULL : c.create_child(my_range,*my_body,my_left,my_incoming,NULL);
                 set_ref_count( (a!=NULL)+(b!=NULL) );
-                body = NULL; 
+                my_body = NULL; 
                 if( a ) spawn(*b);
                 else a = b;
                 return a;
@@ -151,35 +143,38 @@ namespace internal {
     class finish_scan: public task {
         typedef sum_node<Range,Body> sum_node_type;
         typedef final_sum<Range,Body> final_sum_type;
-        final_sum_type** const sum;
-        sum_node_type*& return_slot;
+        final_sum_type** const my_sum;
+        sum_node_type*& my_return_slot;
     public:
-        final_sum_type* right_zombie;
-        sum_node_type& result;
+        final_sum_type* my_right_zombie;
+        sum_node_type& my_result;
 
         /*override*/ task* execute() {
-            __TBB_ASSERT( result.ref_count()==(result.left!=NULL)+(result.right!=NULL), NULL );
-            if( result.left )
-                result.left_is_final = false;
-            if( right_zombie && sum ) 
-                ((*sum)->body).reverse_join(result.left_sum->body);
-            __TBB_ASSERT( !return_slot, NULL );
-            if( right_zombie || result.right ) {
-                return_slot = &result;
+            __TBB_ASSERT( my_result.ref_count()==(my_result.my_left!=NULL)+(my_result.my_right!=NULL), NULL );
+            if( my_result.my_left )
+                my_result.my_left_is_final = false;
+            if( my_right_zombie && my_sum ) 
+                ((*my_sum)->my_body).reverse_join(my_result.my_left_sum->my_body);
+            __TBB_ASSERT( !my_return_slot, NULL );
+            if( my_right_zombie || my_result.my_right ) {
+                my_return_slot = &my_result;
             } else {
-                destroy( result );
+                destroy( my_result );
+            }
+            if( my_right_zombie && !my_sum && !my_result.my_right ) {
+                destroy(*my_right_zombie);
+                my_right_zombie = NULL;
             }
-            if( right_zombie && !sum && !result.right ) destroy(*right_zombie);
             return NULL;
         }
 
         finish_scan( sum_node_type*& return_slot_, final_sum_type** sum_, sum_node_type& result_ ) : 
-            sum(sum_),
-            return_slot(return_slot_), 
-            right_zombie(NULL),
-            result(result_)
+            my_sum(sum_),
+            my_return_slot(return_slot_), 
+            my_right_zombie(NULL),
+            my_result(result_)
         {
-            __TBB_ASSERT( !return_slot, NULL );
+            __TBB_ASSERT( !my_return_slot, NULL );
         }
     };
 
@@ -189,64 +184,64 @@ namespace internal {
     class start_scan: public task {
         typedef sum_node<Range,Body> sum_node_type;
         typedef final_sum<Range,Body> final_sum_type;
-        final_sum_type* body;
+        final_sum_type* my_body;
         /** Non-null if caller is requesting total. */
-        final_sum_type** sum; 
-        sum_node_type** return_slot;
+        final_sum_type** my_sum; 
+        sum_node_type** my_return_slot;
         /** Null if computing root. */
-        sum_node_type* parent_sum;
-        bool is_final;
-        bool is_right_child;
-        Range range;
-        typename Partitioner::partition_type partition;
+        sum_node_type* my_parent_sum;
+        bool my_is_final;
+        bool my_is_right_child;
+        Range my_range;
+        typename Partitioner::partition_type my_partition;
         /*override*/ task* execute();
     public:
         start_scan( sum_node_type*& return_slot_, start_scan& parent_, sum_node_type* parent_sum_ ) :
-            body(parent_.body),
-            sum(parent_.sum),
-            return_slot(&return_slot_),
-            parent_sum(parent_sum_),
-            is_final(parent_.is_final),
-            is_right_child(false),
-            range(parent_.range,split()),
-            partition(parent_.partition,split())
+            my_body(parent_.my_body),
+            my_sum(parent_.my_sum),
+            my_return_slot(&return_slot_),
+            my_parent_sum(parent_sum_),
+            my_is_final(parent_.my_is_final),
+            my_is_right_child(false),
+            my_range(parent_.my_range,split()),
+            my_partition(parent_.my_partition,split())
         {
-            __TBB_ASSERT( !*return_slot, NULL );
+            __TBB_ASSERT( !*my_return_slot, NULL );
         }
 
         start_scan( sum_node_type*& return_slot_, const Range& range_, final_sum_type& body_, const Partitioner& partitioner_) :
-            body(&body_),
-            sum(NULL),
-            return_slot(&return_slot_),
-            parent_sum(NULL),
-            is_final(true),
-            is_right_child(false),
-            range(range_),
-            partition(partitioner_)
+            my_body(&body_),
+            my_sum(NULL),
+            my_return_slot(&return_slot_),
+            my_parent_sum(NULL),
+            my_is_final(true),
+            my_is_right_child(false),
+            my_range(range_),
+            my_partition(partitioner_)
         {
-            __TBB_ASSERT( !*return_slot, NULL );
+            __TBB_ASSERT( !*my_return_slot, NULL );
         }
 
-        static void run(  const Range& range, Body& body, const Partitioner& partitioner ) {
-            if( !range.empty() ) {
+        static void run( const Range& range_, Body& body_, const Partitioner& partitioner_ ) {
+            if( !range_.empty() ) {
                 typedef internal::start_scan<Range,Body,Partitioner> start_pass1_type;
                 internal::sum_node<Range,Body>* root = NULL;
                 typedef internal::final_sum<Range,Body> final_sum_type;
-                final_sum_type* temp_body = new(task::allocate_root()) final_sum_type( body );
+                final_sum_type* temp_body = new(task::allocate_root()) final_sum_type( body_ );
                 start_pass1_type& pass1 = *new(task::allocate_root()) start_pass1_type(
-                    /*return_slot=*/root,
-                    range,
+                    /*my_return_slot=*/root,
+                    range_,
                     *temp_body,
-                    partitioner );
+                    partitioner_ );
                 task::spawn_root_and_wait( pass1 );
                 if( root ) {
-                    root->body = temp_body;
-                    root->incoming = NULL;
-                    root->stuff_last = &body;
+                    root->my_body = temp_body;
+                    root->my_incoming = NULL;
+                    root->my_stuff_last = &body_;
                     task::spawn_root_and_wait( *root );
                 } else {
-                    body.assign(temp_body->body);
-                    temp_body->finish_construction( range, NULL );
+                    body_.assign(temp_body->my_body);
+                    temp_body->finish_construction( range_, NULL );
                     temp_body->destroy(*temp_body);
                 }
             }
@@ -256,47 +251,47 @@ namespace internal {
     template<typename Range, typename Body, typename Partitioner>
     task* start_scan<Range,Body,Partitioner>::execute() {
         typedef internal::finish_scan<Range,Body> finish_pass1_type;
-        finish_pass1_type* p = parent_sum ? static_cast<finish_pass1_type*>( parent() ) : NULL;
+        finish_pass1_type* p = my_parent_sum ? static_cast<finish_pass1_type*>( parent() ) : NULL;
         // Inspecting p->result.left_sum would ordinarily be a race condition.
         // But we inspect it only if we are not a stolen task, in which case we
         // know that task assigning to p->result.left_sum has completed.
-        bool treat_as_stolen = is_right_child && (is_stolen_task() || body!=p->result.left_sum);
+        bool treat_as_stolen = my_is_right_child && (is_stolen_task() || my_body!=p->my_result.my_left_sum);
         if( treat_as_stolen ) {
             // Invocation is for right child that has been really stolen or needs to be virtually stolen
-            p->right_zombie = body = new( allocate_root() ) final_sum_type(body->body);
-            is_final = false;
+            p->my_right_zombie = my_body = new( allocate_root() ) final_sum_type(my_body->my_body);
+            my_is_final = false;
         }
         task* next_task = NULL;
-        if( (is_right_child && !treat_as_stolen) || !range.is_divisible() || partition.should_execute_range(*this) ) {
-            if( is_final )
-                (body->body)( range, final_scan_tag() );
-            else if( sum )
-                (body->body)( range, pre_scan_tag() );
-            if( sum ) 
-                *sum = body;
-            __TBB_ASSERT( !*return_slot, NULL );
+        if( (my_is_right_child && !treat_as_stolen) || !my_range.is_divisible() || my_partition.should_execute_range(*this) ) {
+            if( my_is_final )
+                (my_body->my_body)( my_range, final_scan_tag() );
+            else if( my_sum )
+                (my_body->my_body)( my_range, pre_scan_tag() );
+            if( my_sum ) 
+                *my_sum = my_body;
+            __TBB_ASSERT( !*my_return_slot, NULL );
         } else {
             sum_node_type* result;
-            if( parent_sum ) 
-                result = new(allocate_additional_child_of(*parent_sum)) sum_node_type(range,/*left_is_final=*/is_final);
+            if( my_parent_sum ) 
+                result = new(allocate_additional_child_of(*my_parent_sum)) sum_node_type(my_range,/*my_left_is_final=*/my_is_final);
             else
-                result = new(task::allocate_root()) sum_node_type(range,/*left_is_final=*/is_final);
-            finish_pass1_type& c = *new( allocate_continuation()) finish_pass1_type(*return_slot,sum,*result);
+                result = new(task::allocate_root()) sum_node_type(my_range,/*my_left_is_final=*/my_is_final);
+            finish_pass1_type& c = *new( allocate_continuation()) finish_pass1_type(*my_return_slot,my_sum,*result);
             // Split off right child
-            start_scan& b = *new( c.allocate_child() ) start_scan( /*return_slot=*/result->right, *this, result );
-            b.is_right_child = true;    
+            start_scan& b = *new( c.allocate_child() ) start_scan( /*my_return_slot=*/result->my_right, *this, result );
+            b.my_is_right_child = true;    
             // Left child is recycling of *this.  Must recycle this before spawning b, 
             // otherwise b might complete and decrement c.ref_count() to zero, which
             // would cause c.execute() to run prematurely.
             recycle_as_child_of(c);
             c.set_ref_count(2);
             c.spawn(b);
-            sum = &result->left_sum;
-            return_slot = &result->left;
-            is_right_child = false;
+            my_sum = &result->my_left_sum;
+            my_return_slot = &result->my_left;
+            my_is_right_child = false;
             next_task = this;
-            parent_sum = result; 
-            __TBB_ASSERT( !*return_slot, NULL );
+            my_parent_sum = result; 
+            __TBB_ASSERT( !*my_return_slot, NULL );
         }
         return next_task;
     } 
index cdfbb6102b4edddeb0c3667a8b37fdc5d83066a5..1d33c1f70920fc34f541adb929061c22fb8e3cf4 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_sort_H
@@ -31,6 +23,7 @@
 
 #include "parallel_for.h"
 #include "blocked_range.h"
+#include "internal/_range_iterator.h"
 #include <algorithm>
 #include <iterator>
 #include <functional>
@@ -75,10 +68,11 @@ public:
     bool is_divisible() const {return size>=grainsize;}
 
     quick_sort_range( quick_sort_range& range, split ) : comp(range.comp) {
+        using std::swap;
         RandomAccessIterator array = range.begin;
         RandomAccessIterator key0 = range.begin; 
         size_t m = pseudo_median_of_nine(array, range);
-        if (m) std::swap ( array[0], array[m] );
+        if (m) swap ( array[0], array[m] );
 
         size_t i=0;
         size_t j=range.size;
@@ -96,11 +90,11 @@ public:
                 ++i;
             } while( comp( array[i],*key0 ));
             if( i==j ) goto partition;
-            std::swap( array[i], array[j] );
+            swap( array[i], array[j] );
         }
 partition:
         // Put the partition key were it belongs
-        std::swap( array[j], *key0 );
+        swap( array[j], *key0 );
         // array[l..j) is less or equal to key.
         // array(j..r) is greater or equal to key.
         // array[j] is equal to key
@@ -216,6 +210,34 @@ inline void parallel_sort( RandomAccessIterator begin, RandomAccessIterator end
     parallel_sort( begin, end, std::less< typename std::iterator_traits<RandomAccessIterator>::value_type >() );
 }
 
+//! Sorts the data in rng using the given comparator
+/** @ingroup algorithms **/
+template<typename Range, typename Compare>
+void parallel_sort(Range& rng, const Compare& comp) {
+    parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp);
+}
+
+//! Sorts the data in const rng using the given comparator
+/** @ingroup algorithms **/
+template<typename Range, typename Compare>
+void parallel_sort(const Range& rng, const Compare& comp) {
+    parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng), comp);
+}
+
+//! Sorts the data in rng with a default comparator \c std::less<RandomAccessIterator>
+/** @ingroup algorithms **/
+template<typename Range>
+void parallel_sort(Range& rng) {
+    parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng));
+}
+
+//! Sorts the data in const rng with a default comparator \c std::less<RandomAccessIterator>
+/** @ingroup algorithms **/
+template<typename Range>
+void parallel_sort(const Range& rng) {
+    parallel_sort(tbb::internal::first(rng), tbb::internal::last(rng));
+}
+
 //! Sorts the data in the range \c [begin,end) with a default comparator \c std::less<T>
 /** @ingroup algorithms **/
 template<typename T>
index 94f979598c86e14fb283157299a81dea25366f5b..a1db8341359cc832754cc24a4e00cc1a17eee508 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_parallel_while
index 9301be83f04c3d20631d9c152305565da8fca6fd..c1a24d269c1d3aa3265e4ea297e05180294e40ef 100644 (file)
@@ -1,50 +1,60 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_partitioner_H
 #define __TBB_partitioner_H
 
 #ifndef __TBB_INITIAL_CHUNKS
+// initial task divisions per thread
 #define __TBB_INITIAL_CHUNKS 2
 #endif
 #ifndef __TBB_RANGE_POOL_CAPACITY
+// maximum number of elements in range pool
 #define __TBB_RANGE_POOL_CAPACITY 8
 #endif
 #ifndef __TBB_INIT_DEPTH
+// initial value for depth of range pool
 #define __TBB_INIT_DEPTH 5
 #endif
+#ifndef __TBB_DEMAND_DEPTH_ADD
+// when imbalance is found range splits this value times more
+#define __TBB_DEMAND_DEPTH_ADD 2
+#endif
+#ifndef __TBB_STATIC_THRESHOLD
+// necessary number of clocks for the work to be distributed among all tasks
+#define __TBB_STATIC_THRESHOLD 40000
+#endif
+#if __TBB_DEFINE_MIC
+#define __TBB_NONUNIFORM_TASK_CREATION 1
+#ifdef __TBB_machine_time_stamp
+#define __TBB_USE_MACHINE_TIME_STAMPS 1
+#define __TBB_task_duration() __TBB_STATIC_THRESHOLD
+#endif // __TBB_machine_time_stamp
+#endif // __TBB_DEFINE_MIC
 
 #include "task.h"
 #include "aligned_space.h"
 #include "atomic.h"
 
 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
-    // Workaround for overzealous compiler warnings 
+    // Workaround for overzealous compiler warnings
     #pragma warning (push)
     #pragma warning (disable: 4244)
 #endif
@@ -54,19 +64,19 @@ namespace tbb {
 class auto_partitioner;
 class simple_partitioner;
 class affinity_partitioner;
-namespace interface6 {
+namespace interface7 {
     namespace internal {
         class affinity_partition_type;
     }
 }
 
-namespace internal {
+namespace internal { //< @cond INTERNAL
 size_t __TBB_EXPORTED_FUNC get_initial_auto_partitioner_divisor();
 
 //! Defines entry point for affinity partitioner into tbb run-time library.
 class affinity_partitioner_base_v3: no_copy {
     friend class tbb::affinity_partitioner;
-    friend class tbb::interface6::internal::affinity_partition_type;
+    friend class tbb::interface7::internal::affinity_partition_type;
     //! Array that remembers affinities of tree positions to affinity_id.
     /** NULL if my_size==0. */
     affinity_id* my_array;
@@ -95,16 +105,15 @@ public:
 
 template<typename Range, typename Body, typename Partitioner> class start_scan;
 
-} // namespace internal
-//! @endcond
+} //< namespace internal @endcond
 
 namespace serial {
-namespace interface6 {
+namespace interface7 {
 template<typename Range, typename Body, typename Partitioner> class start_for;
 }
 }
 
-namespace interface6 {
+namespace interface7 {
 //! @cond INTERNAL
 namespace internal {
 using namespace tbb::internal;
@@ -114,24 +123,25 @@ template<typename Range, typename Body, typename Partitioner> class start_reduce
 //! Join task node that contains shared flag for stealing feedback
 class flag_task: public task {
 public:
-    tbb::atomic<bool> child_stolen;
-    flag_task() { child_stolen = false; }
+    tbb::atomic<bool> my_child_stolen;
+    flag_task() { my_child_stolen = false; }
     task* execute() { return NULL; }
-};
-
-//! Task to signal the demand without carrying the work
-class signal_task: public task {
-public:
-    task* execute() {
-        if( is_stolen_task() ) {
-            static_cast<flag_task*>(parent())->child_stolen = true;
-        }
-        return NULL;
+    static void mark_task_stolen(task &t) {
+        tbb::atomic<bool> &flag = static_cast<flag_task*>(t.parent())->my_child_stolen;
+#if TBB_USE_THREADING_TOOLS
+        // Threading tools respect lock prefix but report false-positive data-race via plain store
+        flag.fetch_and_store<release>(true);
+#else
+        flag = true;
+#endif //TBB_USE_THREADING_TOOLS
+    }
+    static bool is_peer_stolen(task &t) {
+        return static_cast<flag_task*>(t.parent())->my_child_stolen;
     }
 };
 
 //! Depth is a relative depth of recursive division inside a range pool. Relative depth allows
-//! infinite absolute depth of the recursion for heavily imbalanced workloads with range represented
+//! infinite absolute depth of the recursion for heavily unbalanced workloads with range represented
 //! by a number that cannot fit into machine word.
 typedef unsigned char depth_t;
 
@@ -148,7 +158,7 @@ public:
     //! initialize via first range in pool
     range_vector(const T& elem) : my_head(0), my_tail(0), my_size(1) {
         my_depth[0] = 0;
-        new( my_pool.begin() ) T(elem);//TODO: std::move?
+        new( static_cast<void *>(my_pool.begin()) ) T(elem);//TODO: std::move?
     }
     ~range_vector() {
         while( !empty() ) pop_back();
@@ -158,8 +168,7 @@ public:
     //! Populates range pool via ranges up to max depth or while divisible
     //! max_depth starts from 0, e.g. value 2 makes 3 ranges in the pool up to two 1/4 pieces
     void split_to_fill(depth_t max_depth) {
-        while( my_size < MaxCapacity && my_depth[my_head] < max_depth
-          && my_pool.begin()[my_head].is_divisible() ) {
+        while( my_size < MaxCapacity && is_divisible(max_depth) ) {
             depth_t prev = my_head;
             my_head = (my_head + 1) % MaxCapacity;
             new(my_pool.begin()+my_head) T(my_pool.begin()[prev]); // copy TODO: std::move?
@@ -194,76 +203,65 @@ public:
         __TBB_ASSERT(my_size > 0, "range_vector::front_depth() with empty size");
         return my_depth[my_tail];
     }
+    depth_t back_depth() {
+        __TBB_ASSERT(my_size > 0, "range_vector::back_depth() with empty size");
+        return my_depth[my_head];
+    }
+    bool is_divisible(depth_t max_depth) {
+        return back_depth() < max_depth && back().is_divisible();
+    }
 };
 
 //! Provides default methods for partition objects and common algorithm blocks.
 template <typename Partition>
 struct partition_type_base {
+    typedef split split_type;
     // decision makers
     void set_affinity( task & ) {}
     void note_affinity( task::affinity_id ) {}
     bool check_being_stolen(task &) { return false; } // part of old should_execute_range()
     bool check_for_demand(task &) { return false; }
-    bool divisions_left() { return true; } // part of old should_execute_range()
-    bool should_create_trap() { return false; }
+    bool is_divisible() { return true; } // part of old should_execute_range()
     depth_t max_depth() { return 0; }
     void align_depth(depth_t) { }
+    template <typename Range> split_type get_split() { return split(); }
+
     // common function blocks
-    Partition& derived() { return *static_cast<Partition*>(this); }
-    template<typename StartType>
-    flag_task* split_work(StartType &start) {
-        flag_task* parent_ptr = start.create_continuation(); // the type here is to express expectation
-        start.set_parent(parent_ptr);
-        parent_ptr->set_ref_count(2);
-        StartType& right_work = *new( parent_ptr->allocate_child() ) StartType(start, split());
-        start.spawn(right_work);
-        return parent_ptr;
-    }
+    Partition& self() { return *static_cast<Partition*>(this); } // CRTP helper
     template<typename StartType, typename Range>
     void execute(StartType &start, Range &range) {
-        // The algorithm in a few words ([]-denotes calls to decision mathods of partitioner):
+        // The algorithm in a few words ([]-denotes calls to decision methods of partitioner):
         // [If this task is stolen, adjust depth and divisions if necessary, set flag].
         // If range is divisible {
         //    Spread the work while [initial divisions left];
         //    Create trap task [if necessary];
         // }
         // If not divisible or [max depth is reached], execute, else do the range pool part
-        task* parent_ptr = start.parent();
-        if( range.is_divisible() ) {
-            if( derived().divisions_left() )
-                do parent_ptr = split_work(start); // split until divisions_left()
-                while( range.is_divisible() && derived().divisions_left() );
-            if( derived().should_create_trap() ) { // only for range pool
-                if( parent_ptr->ref_count() > 1 ) { // create new parent if necessary
-                    parent_ptr = start.create_continuation();
-                    start.set_parent(parent_ptr);
-                } else __TBB_ASSERT(parent_ptr->ref_count() == 1, NULL);
-                parent_ptr->set_ref_count(2); // safe because parent has only one reference
-                signal_task& right_signal = *new( parent_ptr->allocate_child() ) signal_task();
-                start.spawn(right_signal); // pure signal is to avoid deep recursion in the end
+        if ( range.is_divisible() ) {
+            if ( self().is_divisible() ) {
+                do { // split until is divisible
+                    typename Partition::split_type split_obj = self().template get_split<Range>();
+                    start.offer_work( split_obj );
+                } while ( range.is_divisible() && self().is_divisible() );
             }
         }
-        if( !range.is_divisible() || !derived().max_depth() )
+        if( !range.is_divisible() || !self().max_depth() )
             start.run_body( range ); // simple partitioner goes always here
         else { // do range pool
             internal::range_vector<Range, Partition::range_pool_size> range_pool(range);
             do {
-                range_pool.split_to_fill(derived().max_depth()); // fill range pool
-                if( derived().check_for_demand( start ) ) {
+                range_pool.split_to_fill(self().max_depth()); // fill range pool
+                if( self().check_for_demand( start ) ) {
                     if( range_pool.size() > 1 ) {
-                        parent_ptr = start.create_continuation();
-                        start.set_parent(parent_ptr);
-                        parent_ptr->set_ref_count(2);
-                        StartType& right_work = *new( parent_ptr->allocate_child() ) StartType(start, range_pool.front(), range_pool.front_depth());
-                        start.spawn(right_work);
+                        start.offer_work( range_pool.front(), range_pool.front_depth() );
                         range_pool.pop_front();
                         continue;
                     }
-                    if( range_pool.back().is_divisible() ) // was not enough depth to fork a task
-                        continue; // note: check_for_demand() should guarantee increasing max_depth() next time
+                    if( range_pool.is_divisible(self().max_depth()) ) // was not enough depth to fork a task
+                        continue; // note: next split_to_fill() should split range at least once
                 }
                 start.run_body( range_pool.back() );
-                range_pool.pop_back();  
+                range_pool.pop_back();
             } while( !range_pool.empty() && !start.is_cancelled() );
         }
     }
@@ -271,60 +269,64 @@ struct partition_type_base {
 
 //! Provides default methods for auto (adaptive) partition objects.
 template <typename Partition>
-struct auto_partition_type_base : partition_type_base<Partition> {
+struct adaptive_partition_type_base : partition_type_base<Partition> {
     size_t my_divisor;
     depth_t my_max_depth;
-    auto_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) {
-        my_divisor = tbb::internal::get_initial_auto_partitioner_divisor()*__TBB_INITIAL_CHUNKS/4;
+    static const unsigned factor = 1;
+    adaptive_partition_type_base() : my_max_depth(__TBB_INIT_DEPTH) {
+        my_divisor = tbb::internal::get_initial_auto_partitioner_divisor() / 4 * Partition::factor;
         __TBB_ASSERT(my_divisor, "initial value of get_initial_auto_partitioner_divisor() is not valid");
     }
-    auto_partition_type_base(auto_partition_type_base &src, split) {
+    adaptive_partition_type_base(adaptive_partition_type_base &src, split) {
         my_max_depth = src.my_max_depth;
+#if TBB_USE_ASSERT
+        size_t old_divisor = src.my_divisor;
+#endif
+
 #if __TBB_INITIAL_TASK_IMBALANCE
         if( src.my_divisor <= 1 ) my_divisor = 0;
-        else my_divisor = src.my_divisor = (src.my_divisor+1u) / 2u;
+        else my_divisor = src.my_divisor = (src.my_divisor + 1u) / 2u;
 #else
         my_divisor = src.my_divisor / 2u;
         src.my_divisor = src.my_divisor - my_divisor; // TODO: check the effect separately
-        if(my_divisor) src.my_max_depth += static_cast<depth_t>(__TBB_Log2(src.my_divisor/my_divisor));
+        if (my_divisor) src.my_max_depth += static_cast<depth_t>(__TBB_Log2(src.my_divisor / my_divisor));
+#endif
+        // For affinity_partitioner, my_divisor indicates the number of affinity array indices the task reserves.
+        // A task which has only one index must produce the right split without reserved index in order to avoid
+        // it to be overwritten in note_affinity() of the created (right) task.
+        // I.e. a task created deeper than the affinity array can remember must not save its affinity (LIFO order)
+        __TBB_ASSERT( (old_divisor <= 1 && my_divisor == 0) ||
+                      (old_divisor > 1 && my_divisor != 0), NULL);
+    }
+    adaptive_partition_type_base(adaptive_partition_type_base &src, const proportional_split& split_obj) {
+        my_max_depth = src.my_max_depth;
+#if __TBB_ENABLE_RANGE_FEEDBACK
+        my_divisor = size_t(float(src.my_divisor) * float(split_obj.right())
+                            / float(split_obj.left() + split_obj.right()));
+#else
+        my_divisor = split_obj.right() * Partition::factor;
 #endif
+        src.my_divisor -= my_divisor;
     }
     bool check_being_stolen( task &t) { // part of old should_execute_range()
-        if( !my_divisor ) {
-            my_divisor = 1; // todo: replace by on-stack flag (partition_state's member)?
-            if( t.is_stolen_task() ) {
+        if( !my_divisor ) { // if not from the top P tasks of binary tree
+            my_divisor = 1; // TODO: replace by on-stack flag (partition_state's member)?
+            if( t.is_stolen_task() && t.parent()->ref_count() >= 2 ) { // runs concurrently with the left task
 #if TBB_USE_EXCEPTIONS
                 // RTTI is available, check whether the cast is valid
                 __TBB_ASSERT(dynamic_cast<flag_task*>(t.parent()), 0);
-                // correctess of the cast rely on avoiding the root task for which:
+                // correctness of the cast relies on avoiding the root task for which:
                 // - initial value of my_divisor != 0 (protected by separate assertion)
-                // - is_stolen_task() always return false for the root task.
+                // - is_stolen_task() always returns false for the root task.
 #endif
-                static_cast<flag_task*>(t.parent())->child_stolen = true;
-                my_max_depth++;
+                flag_task::mark_task_stolen(t);
+                if( !my_max_depth ) my_max_depth++;
+                my_max_depth += __TBB_DEMAND_DEPTH_ADD;
                 return true;
             }
         }
         return false;
     }
-    bool divisions_left() { // part of old should_execute_range()
-        if( my_divisor > 1 ) return true;
-        if( my_divisor && my_max_depth > 1 ) { // can split the task and once more internally. TODO: on-stack flag instead
-            // keep same fragmentation while splitting for the local task pool
-            my_max_depth--;
-            my_divisor = 0;
-            return true;
-        } else return false;
-    }
-    bool should_create_trap() {
-        return my_divisor > 0;
-    }
-    bool check_for_demand(task &t) {
-        if( static_cast<flag_task*>(t.parent())->child_stolen ) {
-            my_max_depth++;
-            return true;
-        } else return false;
-    }
     void align_depth(depth_t base) {
         __TBB_ASSERT(base <= my_max_depth, 0);
         my_max_depth -= base;
@@ -332,75 +334,187 @@ struct auto_partition_type_base : partition_type_base<Partition> {
     depth_t max_depth() { return my_max_depth; }
 };
 
+//! Helper that enables one or the other code branches (see example in is_splittable_in_proportion)
+template<bool C, typename T = void> struct enable_if { typedef T type; };
+template<typename T> struct enable_if<false, T> { };
+
+//! Class determines whether template parameter has static boolean constant
+//! 'is_splittable_in_proportion' initialized with value of 'true' or not.
+/** If template parameter has such field that has been initialized with non-zero
+ *  value then class field will be set to 'true', otherwise - 'false'
+ */
+template <typename Range>
+class is_splittable_in_proportion {
+private:
+    typedef char yes[1];
+    typedef char no [2];
+
+    template <typename range_type> static yes& decide(typename enable_if<range_type::is_splittable_in_proportion>::type *);
+    template <typename range_type> static no& decide(...);
+public:
+    // equals to 'true' if and only if static const variable 'is_splittable_in_proportion' of template parameter
+    // initialized with the value of 'true'
+    static const bool value = (sizeof(decide<Range>(0)) == sizeof(yes));
+};
+
 //! Provides default methods for affinity (adaptive) partition objects.
-class affinity_partition_type : public auto_partition_type_base<affinity_partition_type> {
+class affinity_partition_type : public adaptive_partition_type_base<affinity_partition_type> {
     static const unsigned factor_power = 4;
-    static const unsigned factor = 1<<factor_power;
-    bool my_delay;
-    unsigned map_begin, map_end, map_mid;
+    enum {
+        start = 0,
+        run,
+        pass
+    } my_delay;
+#ifdef __TBB_USE_MACHINE_TIME_STAMPS
+    machine_tsc_t my_dst_tsc;
+#endif
+    size_t my_begin;
     tbb::internal::affinity_id* my_array;
-    void set_mid() {
-        unsigned d = (map_end - map_begin)/2; // we could add 1 but it is rather for LIFO affinity
-        if( d > factor )
-            d &= 0u-factor;
-        map_mid = map_end - d;
-    }
 public:
-    affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& ap ) {
-        __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" ); 
+    static const unsigned factor = 1 << factor_power; // number of slots in affinity array per task
+    typedef proportional_split split_type;
+
+    affinity_partition_type( tbb::internal::affinity_partitioner_base_v3& ap )
+        : adaptive_partition_type_base<affinity_partition_type>(), my_delay(start)
+#ifdef __TBB_USE_MACHINE_TIME_STAMPS
+        , my_dst_tsc(0)
+#endif
+    {
+        __TBB_ASSERT( (factor&(factor-1))==0, "factor must be power of two" );
         ap.resize(factor);
         my_array = ap.my_array;
-        map_begin = 0;
-        map_end = unsigned(ap.my_size);
-        set_mid();
-        my_delay = true;
-        my_divisor /= __TBB_INITIAL_CHUNKS; // let excatly P tasks to be distributed across workers
-        my_max_depth = factor_power+1; // the first factor_power ranges will be spawned, and >=1 ranges should left
+        my_begin = 0;
+        my_max_depth = factor_power + 1; // the first factor_power ranges will be spawned, and >=1 ranges should be left
         __TBB_ASSERT( my_max_depth < __TBB_RANGE_POOL_CAPACITY, 0 );
     }
     affinity_partition_type(affinity_partition_type& p, split)
-        : auto_partition_type_base<affinity_partition_type>(p, split()), my_array(p.my_array) {
-        __TBB_ASSERT( p.map_end-p.map_begin<factor || (p.map_end-p.map_begin)%factor==0, NULL );
-        map_end = p.map_end;
-        map_begin = p.map_end = p.map_mid;
-        set_mid(); p.set_mid();
-        my_delay = p.my_delay;
+        : adaptive_partition_type_base<affinity_partition_type>(p, split()),
+          my_delay(pass),
+#ifdef __TBB_USE_MACHINE_TIME_STAMPS
+          my_dst_tsc(0),
+#endif
+          my_array(p.my_array) {
+        // the sum of the divisors represents original value of p.my_divisor before split
+        __TBB_ASSERT(my_divisor + p.my_divisor <= factor, NULL);
+        my_begin = p.my_begin + p.my_divisor;
+    }
+    affinity_partition_type(affinity_partition_type& p, const proportional_split& split_obj)
+        : adaptive_partition_type_base<affinity_partition_type>(p, split_obj),
+          my_delay(start),
+#ifdef __TBB_USE_MACHINE_TIME_STAMPS
+          my_dst_tsc(0),
+#endif
+          my_array(p.my_array) {
+        size_t total_divisor = my_divisor + p.my_divisor;
+        __TBB_ASSERT(total_divisor % factor == 0, NULL);
+        my_divisor = (my_divisor + factor/2) & (0u - factor);
+#if __TBB_ENABLE_RANGE_FEEDBACK
+        if (!my_divisor)
+            my_divisor = factor;
+        else if (my_divisor == total_divisor)
+            my_divisor = total_divisor - factor;
+#endif
+        p.my_divisor = total_divisor - my_divisor;
+        __TBB_ASSERT(my_divisor && p.my_divisor, NULL);
+        my_begin = p.my_begin + p.my_divisor;
     }
     void set_affinity( task &t ) {
-        if( map_begin<map_end )
-            t.set_affinity( my_array[map_begin] );
+        if( my_divisor ) {
+            if( !my_array[my_begin] )
+                // TODO: consider code reuse for static_paritioner
+                t.set_affinity( affinity_id(my_begin / factor + 1) );
+            else
+                t.set_affinity( my_array[my_begin] );
+        }
     }
     void note_affinity( task::affinity_id id ) {
-        if( map_begin<map_end ) 
-            my_array[map_begin] = id;
+        if( my_divisor )
+            my_array[my_begin] = id;
     }
     bool check_for_demand( task &t ) {
-        if( !my_delay ) {
-            if( map_mid<map_end ) {
-                __TBB_ASSERT(my_max_depth>__TBB_Log2(map_end-map_mid), 0);
-                return true;// do not do my_max_depth++ here, but be sure my_max_depth is big enough
+        if( pass == my_delay ) {
+            if( my_divisor > 1 ) // produce affinitized tasks while they have slot in array
+                return true; // do not do my_max_depth++ here, but be sure range_pool is splittable once more
+            else if( my_divisor && my_max_depth ) { // make balancing task
+                my_divisor = 0; // once for each task; depth will be decreased in align_depth()
+                return true;
             }
-            if( static_cast<flag_task*>(t.parent())->child_stolen ) {
-                my_max_depth++;
+            else if( flag_task::is_peer_stolen(t) ) {
+                my_max_depth += __TBB_DEMAND_DEPTH_ADD;
                 return true;
             }
-        } else my_delay = false;
+        } else if( start == my_delay ) {
+#ifndef __TBB_USE_MACHINE_TIME_STAMPS
+            my_delay = pass;
+#else
+            my_dst_tsc = __TBB_machine_time_stamp() + __TBB_task_duration();
+            my_delay = run;
+        } else if( run == my_delay ) {
+            if( __TBB_machine_time_stamp() < my_dst_tsc ) {
+                __TBB_ASSERT(my_max_depth > 0, NULL);
+                return false;
+            }
+            my_delay = pass;
+            return true;
+#endif // __TBB_USE_MACHINE_TIME_STAMPS
+        }
         return false;
     }
-    bool divisions_left() { // part of old should_execute_range()
-        return my_divisor > 1;
+    bool is_divisible() { // part of old should_execute_range()
+        return my_divisor > factor;
     }
-    bool should_create_trap() {
-        return true; // TODO: rethink for the stage after memorizing level
+
+#if _MSC_VER && !defined(__INTEL_COMPILER)
+    // Suppress "conditional expression is constant" warning.
+    #pragma warning( push )
+    #pragma warning( disable: 4127 )
+#endif
+    template <typename Range>
+    split_type get_split() {
+        if (is_splittable_in_proportion<Range>::value) {
+            size_t size = my_divisor / factor;
+#if __TBB_NONUNIFORM_TASK_CREATION
+            size_t right = (size + 2) / 3;
+#else
+            size_t right = size / 2;
+#endif
+            size_t left = size - right;
+            return split_type(left, right);
+        } else {
+            return split_type(1, 1);
+        }
     }
+#if _MSC_VER && !defined(__INTEL_COMPILER)
+    #pragma warning( pop )
+#endif // warning 4127 is back
+
     static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY;
 };
 
-class auto_partition_type: public auto_partition_type_base<auto_partition_type> {
+class auto_partition_type: public adaptive_partition_type_base<auto_partition_type> {
 public:
-    auto_partition_type( const auto_partitioner& ) {}
+    auto_partition_type( const auto_partitioner& ) {
+        my_divisor *= __TBB_INITIAL_CHUNKS;
+    }
     auto_partition_type( auto_partition_type& src, split)
-      : auto_partition_type_base<auto_partition_type>(src, split()) {}
+      : adaptive_partition_type_base<auto_partition_type>(src, split()) {}
+
+    bool is_divisible() { // part of old should_execute_range()
+        if( my_divisor > 1 ) return true;
+        if( my_divisor && my_max_depth ) { // can split the task. TODO: on-stack flag instead
+            // keep same fragmentation while splitting for the local task pool
+            my_max_depth--;
+            my_divisor = 0; // decrease max_depth once per task
+            return true;
+        } else return false;
+    }
+    bool check_for_demand(task &t) {
+        if( flag_task::is_peer_stolen(t) ) {
+            my_max_depth += __TBB_DEMAND_DEPTH_ADD;
+            return true;
+        } else return false;
+    }
+
     static const unsigned range_pool_size = __TBB_RANGE_POOL_CAPACITY;
 };
 
@@ -411,8 +525,9 @@ public:
     //! simplified algorithm
     template<typename StartType, typename Range>
     void execute(StartType &start, Range &range) {
+        split_type split_obj = split(); // start.offer_work accepts split_type as reference
         while( range.is_divisible() )
-            split_work( start );
+            start.offer_work( split_obj );
         start.run_body( range );
     }
     //static const unsigned range_pool_size = 1; - not necessary because execute() is overridden
@@ -441,16 +556,16 @@ public:
 //! @endcond
 } // namespace interfaceX
 
-//! A simple partitioner 
-/** Divides the range until the range is not divisible. 
+//! A simple partitioner
+/** Divides the range until the range is not divisible.
     @ingroup algorithms */
 class simple_partitioner {
 public:
     simple_partitioner() {}
 private:
-    template<typename Range, typename Body, typename Partitioner> friend class serial::interface6::start_for;
-    template<typename Range, typename Body, typename Partitioner> friend class interface6::internal::start_for;
-    template<typename Range, typename Body, typename Partitioner> friend class interface6::internal::start_reduce;
+    template<typename Range, typename Body, typename Partitioner> friend class serial::interface7::start_for;
+    template<typename Range, typename Body, typename Partitioner> friend class interface7::internal::start_for;
+    template<typename Range, typename Body, typename Partitioner> friend class interface7::internal::start_reduce;
     template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
     // backward compatibility
     class partition_type: public internal::partition_type_base {
@@ -460,10 +575,13 @@ private:
         partition_type( const partition_type&, split ) {}
     };
     // new implementation just extends existing interface
-    typedef interface6::internal::simple_partition_type task_partition_type;
+    typedef interface7::internal::simple_partition_type task_partition_type;
+
+    // TODO: consider to make split_type public
+    typedef interface7::internal::simple_partition_type::split_type split_type;
 };
 
-//! An auto partitioner 
+//! An auto partitioner
 /** The range is initial divided into several large chunks.
     Chunks are further subdivided into smaller pieces if demand detected and they are divisible.
     @ingroup algorithms */
@@ -472,14 +590,17 @@ public:
     auto_partitioner() {}
 
 private:
-    template<typename Range, typename Body, typename Partitioner> friend class serial::interface6::start_for;
-    template<typename Range, typename Body, typename Partitioner> friend class interface6::internal::start_for;
-    template<typename Range, typename Body, typename Partitioner> friend class interface6::internal::start_reduce;
+    template<typename Range, typename Body, typename Partitioner> friend class serial::interface7::start_for;
+    template<typename Range, typename Body, typename Partitioner> friend class interface7::internal::start_for;
+    template<typename Range, typename Body, typename Partitioner> friend class interface7::internal::start_reduce;
     template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
     // backward compatibility
-    typedef interface6::internal::old_auto_partition_type partition_type;
+    typedef interface7::internal::old_auto_partition_type partition_type;
     // new implementation just extends existing interface
-    typedef interface6::internal::auto_partition_type task_partition_type;
+    typedef interface7::internal::auto_partition_type task_partition_type;
+
+    // TODO: consider to make split_type public
+    typedef interface7::internal::auto_partition_type::split_type split_type;
 };
 
 //! An affinity partitioner
@@ -488,14 +609,17 @@ public:
     affinity_partitioner() {}
 
 private:
-    template<typename Range, typename Body, typename Partitioner> friend class serial::interface6::start_for;
-    template<typename Range, typename Body, typename Partitioner> friend class interface6::internal::start_for;
-    template<typename Range, typename Body, typename Partitioner> friend class interface6::internal::start_reduce;
+    template<typename Range, typename Body, typename Partitioner> friend class serial::interface7::start_for;
+    template<typename Range, typename Body, typename Partitioner> friend class interface7::internal::start_for;
+    template<typename Range, typename Body, typename Partitioner> friend class interface7::internal::start_reduce;
     template<typename Range, typename Body, typename Partitioner> friend class internal::start_scan;
     // backward compatibility - for parallel_scan only
-    typedef interface6::internal::old_auto_partition_type partition_type;
+    typedef interface7::internal::old_auto_partition_type partition_type;
     // new implementation just extends existing interface
-    typedef interface6::internal::affinity_partition_type task_partition_type;
+    typedef interface7::internal::affinity_partition_type task_partition_type;
+
+    // TODO: consider to make split_type public
+    typedef interface7::internal::affinity_partition_type::split_type split_type;
 };
 
 } // namespace tbb
index 60fe09b7ca372fec55337bdfd4146915134555a0..3a1d3d899421178346610489893a695ba1c8c7e8 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_pipeline_H 
 #include "tbb_allocator.h"
 #include <cstddef>
 
+#if __TBB_CPP11_TYPE_PROPERTIES_PRESENT || __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT
+#include <type_traits>
+#endif
+
 namespace tbb {
 
 class pipeline;
@@ -43,7 +39,7 @@ class filter;
 namespace internal {
 
 // The argument for PIPELINE_VERSION should be an integer between 2 and 9
-#define __TBB_PIPELINE_VERSION(x) (unsigned char)(x-2)<<1
+#define __TBB_PIPELINE_VERSION(x) ((unsigned char)(x-2)<<1)
 
 typedef unsigned long Token;
 typedef long tokendiff_t;
@@ -211,7 +207,9 @@ public:
 protected:
     thread_bound_filter(mode filter_mode): 
          filter(static_cast<mode>(filter_mode | filter::filter_is_bound))
-    {}
+    {
+        __TBB_ASSERT(filter_mode & filter::filter_is_serial, "thread-bound filters must be serial");
+    }
 public:
     //! If a data item is available, invoke operator() on that item.  
     /** This interface is non-blocking.
@@ -294,7 +292,7 @@ private:
     void __TBB_EXPORTED_METHOD inject_token( task& self );
 
 #if __TBB_TASK_GROUP_CONTEXT
-    //! Does clean up if pipeline is cancelled or exception occured
+    //! Does clean up if pipeline is cancelled or exception occurred
     void clear_filters();
 #endif
 };
@@ -321,7 +319,28 @@ public:
 //! @cond INTERNAL
 namespace internal {
 
-template<typename T> struct is_large_object { enum { r = sizeof(T) > sizeof(void *) }; };
+template<typename T> struct tbb_large_object {enum { value = sizeof(T) > sizeof(void *) }; };
+
+// Obtain type properties in one or another way
+#if   __TBB_CPP11_TYPE_PROPERTIES_PRESENT
+template<typename T> struct tbb_trivially_copyable { enum { value = std::is_trivially_copyable<T>::value }; };
+#elif __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT
+template<typename T> struct tbb_trivially_copyable { enum { value = std::has_trivial_copy_constructor<T>::value }; };
+#else
+// Explicitly list the types we wish to be placed as-is in the pipeline input_buffers.
+template<typename T> struct tbb_trivially_copyable { enum { value = false }; };
+template<typename T> struct tbb_trivially_copyable <T*> { enum { value = true }; };
+template<> struct tbb_trivially_copyable <short> { enum { value = true }; };
+template<> struct tbb_trivially_copyable <unsigned short> { enum { value = true }; };
+template<> struct tbb_trivially_copyable <int> { enum { value = !tbb_large_object<int>::value }; };
+template<> struct tbb_trivially_copyable <unsigned int> { enum { value = !tbb_large_object<int>::value }; };
+template<> struct tbb_trivially_copyable <long> { enum { value = !tbb_large_object<long>::value }; };
+template<> struct tbb_trivially_copyable <unsigned long> { enum { value = !tbb_large_object<long>::value }; };
+template<> struct tbb_trivially_copyable <float> { enum { value = !tbb_large_object<float>::value }; };
+template<> struct tbb_trivially_copyable <double> { enum { value = !tbb_large_object<double>::value }; };
+#endif // Obtaining type properties
+
+template<typename T> struct is_large_object {enum { value = tbb_large_object<T>::value || !tbb_trivially_copyable<T>::value }; };
 
 template<typename T, bool> class token_helper;
 
@@ -388,9 +407,9 @@ class token_helper<T, false> {
 template<typename T, typename U, typename Body>
 class concrete_filter: public tbb::filter {
     const Body& my_body;
-    typedef token_helper<T,is_large_object<T>::r > t_helper;
+    typedef token_helper<T,is_large_object<T>::value > t_helper;
     typedef typename t_helper::pointer t_pointer;
-    typedef token_helper<U,is_large_object<U>::r > u_helper;
+    typedef token_helper<U,is_large_object<U>::value > u_helper;
     typedef typename u_helper::pointer u_pointer;
 
     /*override*/ void* operator()(void* input) {
@@ -400,6 +419,11 @@ class concrete_filter: public tbb::filter {
         return u_helper::cast_to_void_ptr(output_u);
     }
 
+    /*override*/ void finalize(void * input) {
+        t_pointer temp_input = t_helper::cast_from_void_ptr(input);
+        t_helper::destroy_token(temp_input);
+    }
+
 public:
     concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {}
 };
@@ -408,7 +432,7 @@ public:
 template<typename U, typename Body>
 class concrete_filter<void,U,Body>: public filter {
     const Body& my_body;
-    typedef token_helper<U, is_large_object<U>::r > u_helper;
+    typedef token_helper<U, is_large_object<U>::value > u_helper;
     typedef typename u_helper::pointer u_pointer;
 
     /*override*/void* operator()(void*) {
@@ -432,7 +456,7 @@ public:
 template<typename T, typename Body>
 class concrete_filter<T,void,Body>: public filter {
     const Body& my_body;
-    typedef token_helper<T, is_large_object<T>::r > t_helper;
+    typedef token_helper<T, is_large_object<T>::value > t_helper;
     typedef typename t_helper::pointer t_pointer;
    
     /*override*/ void* operator()(void* input) {
@@ -441,6 +465,11 @@ class concrete_filter<T,void,Body>: public filter {
         t_helper::destroy_token(temp_input);
         return NULL;
     }
+    /*override*/ void finalize(void* input) {
+        t_pointer temp_input = t_helper::cast_from_void_ptr(input);
+        t_helper::destroy_token(temp_input);
+    }
+
 public:
     concrete_filter(tbb::filter::mode filter_mode, const Body& body) : filter(filter_mode), my_body(body) {}
 };
index a7e224b2a4c336906c9d9be18b009b517f7cd945..7986b0b45281e69221f4342cf2f64b40a7a0ef1a 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_queuing_mutex_H
@@ -48,9 +40,9 @@
 
 namespace tbb {
 
-//! Queuing lock with local-only spinning.
+//! Queuing mutex with local-only spinning.
 /** @ingroup synchronization */
-class queuing_mutex {
+class queuing_mutex : internal::mutex_copy_deprecated_and_disabled {
 public:
     //! Construct unacquired mutex.
     queuing_mutex() {
@@ -71,6 +63,7 @@ public:
             internal::poison_pointer(next);
 #endif /* TBB_USE_ASSERT */
         }
+
     public:
         //! Construct lock that has not acquired a mutex.
         /** Equivalent to zero-initialization of *this. */
@@ -116,6 +109,7 @@ public:
     static const bool is_rw_mutex = false;
     static const bool is_recursive_mutex = false;
     static const bool is_fair_mutex = true;
+
 private:
     //! The last competitor requesting the lock
     atomic<scoped_lock*> q_tail;
index 644bdfdab1531ba5c447def0740a5718d8e71a06..76df1629004577b7fe33dad913fe94993b2785f0 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_queuing_rw_mutex_H
 
 namespace tbb {
 
-//! Reader-writer lock with local-only spinning.
+//! Queuing reader-writer mutex with local-only spinning.
 /** Adapted from Krieger, Stumm, et al. pseudocode at
     http://www.eecg.toronto.edu/parallel/pubs_abs.html#Krieger_etal_ICPP93
     @ingroup synchronization */
-class queuing_rw_mutex {
+class queuing_rw_mutex : internal::mutex_copy_deprecated_and_disabled {
 public:
     //! Construct unacquired mutex.
     queuing_rw_mutex() {
@@ -69,14 +61,11 @@ public:
 #endif
     }
 
-    class scoped_lock;
-    friend class scoped_lock;
-
     //! The scoped locking pattern
     /** It helps to avoid the common problem of forgetting to release lock.
         It also nicely provides the "node" for queuing locks. */
     class scoped_lock: internal::no_copy {
-        //! Initialize fields
+        //! Initialize fields to mean "no lock held".
         void initialize() {
             my_mutex = NULL;
 #if TBB_USE_ASSERT
@@ -85,6 +74,7 @@ public:
             internal::poison_pointer(my_prev);
 #endif /* TBB_USE_ASSERT */
         }
+
     public:
         //! Construct lock that has not acquired a mutex.
         /** Equivalent to zero-initialization of *this. */
@@ -104,21 +94,21 @@ public:
         //! Acquire lock on given mutex.
         void acquire( queuing_rw_mutex& m, bool write=true );
 
-        //! Try acquire lock on given mutex.
+        //! Acquire lock on given mutex if free (i.e. non-blocking)
         bool try_acquire( queuing_rw_mutex& m, bool write=true );
 
         //! Release lock.
         void release();
 
         //! Upgrade reader to become a writer.
-        /** Returns true if the upgrade happened without re-acquiring the lock and false if opposite */
+        /** Returns whether the upgrade happened without releasing and re-acquiring the lock */
         bool upgrade_to_writer();
 
         //! Downgrade writer to become a reader.
         bool downgrade_to_reader();
 
     private:
-        //! The pointer to the current mutex to work
+        //! The pointer to the mutex owned, or NULL if not holding a mutex.
         queuing_rw_mutex* my_mutex;
 
         //! The pointer to the previous and next competitors for a mutex
index 877234b0a3177232b39bcc90aea9437f6b853549..60d24f3dc200ad2b2ad2d2c7ccaa1c8706f7ccd9 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_reader_writer_lock_H
@@ -58,7 +50,7 @@ namespace interface5 {
         invalid: the end state for all nodes; this is set in the
           destructor so if we encounter this state, we are looking at
           memory that has already been freed
-        
+
         The state diagrams below describe the status transitions.
         Single arrows indicate that the thread that owns the node is
         responsible for the transition; double arrows indicate that
@@ -70,12 +62,12 @@ namespace interface5 {
           |     _____________/       |
           V    V                     V
         active -----------------> invalid
-  
+
         State diagram for scoped_lock_read status:
 
-        waiting 
-          |                        
-          V                        
+        waiting
+          |
+          V
         active ----------------->invalid
 
     */
@@ -97,12 +89,12 @@ namespace interface5 {
     class scoped_lock : tbb::internal::no_copy {
     public:
         friend class reader_writer_lock;
-        //! Construct with blocking attempt to acquire write lock on the passed-in lock 
+
+        //! Construct with blocking attempt to acquire write lock on the passed-in lock
         scoped_lock(reader_writer_lock& lock) {
             internal_construct(lock);
         }
-        
+
         //! Destructor, releases the write lock
         ~scoped_lock() {
             internal_destroy();
@@ -135,16 +127,16 @@ namespace interface5 {
     public:
         friend class reader_writer_lock;
 
-        //! Construct with blocking attempt to acquire read lock on the passed-in lock 
+        //! Construct with blocking attempt to acquire read lock on the passed-in lock
         scoped_lock_read(reader_writer_lock& lock) {
             internal_construct(lock);
         }
 
         //! Destructor, releases the read lock
-        ~scoped_lock_read() { 
+        ~scoped_lock_read() {
             internal_destroy();
         }
-        
+
         void* operator new(size_t s) {
             return tbb::internal::allocate_via_handler_v3(s);
         }
@@ -166,8 +158,8 @@ namespace interface5 {
         void __TBB_EXPORTED_METHOD internal_construct(reader_writer_lock&);
         void __TBB_EXPORTED_METHOD internal_destroy();
     };
-    
-    //! Acquires the reader_writer_lock for write.  
+
+    //! Acquires the reader_writer_lock for write.
     /** If the lock is currently held in write mode by another
         context, the writer will block by spinning on a local
         variable.  Exceptions thrown: improper_lock The context tries
@@ -175,21 +167,21 @@ namespace interface5 {
         ownership of.*/
     void __TBB_EXPORTED_METHOD lock();
 
-    //! Tries to acquire the reader_writer_lock for write.   
+    //! Tries to acquire the reader_writer_lock for write.
     /** This function does not block.  Return Value: True or false,
         depending on whether the lock is acquired or not.  If the lock
         is already held by this acquiring context, try_lock() returns
         false. */
     bool __TBB_EXPORTED_METHOD try_lock();
 
-    //! Acquires the reader_writer_lock for read.    
+    //! Acquires the reader_writer_lock for read.
     /** If the lock is currently held by a writer, this reader will
         block and wait until the writers are done.  Exceptions thrown:
         improper_lock The context tries to acquire a
         reader_writer_lock that it already has write ownership of. */
-    void __TBB_EXPORTED_METHOD lock_read(); 
+    void __TBB_EXPORTED_METHOD lock_read();
 
-    //! Tries to acquire the reader_writer_lock for read.  
+    //! Tries to acquire the reader_writer_lock for read.
     /** This function does not block.  Return Value: True or false,
         depending on whether the lock is acquired or not.  */
     bool __TBB_EXPORTED_METHOD try_lock_read();
@@ -206,7 +198,7 @@ namespace interface5 {
     bool start_write(scoped_lock *);
     //! Sets writer_head to w and attempts to unblock
     void set_next_writer(scoped_lock *w);
-    //! Relinquishes write lock to next waiting writer or group of readers 
+    //! Relinquishes write lock to next waiting writer or group of readers
     void end_write(scoped_lock *);
     //! Checks if current thread holds write lock
     bool is_current_writer();
@@ -228,7 +220,7 @@ namespace interface5 {
     //! Writer that owns the mutex; tbb_thread::id() otherwise.
     tbb_thread::id my_current_writer;
     //! Status of mutex
-    atomic<unsigned> rdr_count_and_flags;
+    atomic<uintptr_t> rdr_count_and_flags; // used with __TBB_AtomicOR, which assumes uintptr_t
 };
 
 } // namespace interface5
index 185fd19dd24a207b7f3d1f802aac235be52b2e31..1e41d90a5a31524af95a3fef572ba341eb5eb141 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_recursive_mutex_H
@@ -44,7 +36,7 @@ namespace tbb {
 //! Mutex that allows recursive mutex acquisition.
 /** Mutex that allows recursive mutex acquisition.
     @ingroup synchronization */
-class recursive_mutex {
+class recursive_mutex : internal::mutex_copy_deprecated_and_disabled {
 public:
     //! Construct unacquired recursive_mutex.
     recursive_mutex() {
@@ -52,7 +44,7 @@ public:
         internal_construct();
 #else
   #if _WIN32||_WIN64
-        InitializeCriticalSection(&impl);
+        InitializeCriticalSectionEx(&impl, 4000, 0);
   #else
         pthread_mutexattr_t mtx_attr;
         int error_code = pthread_mutexattr_init( &mtx_attr );
@@ -165,13 +157,15 @@ public:
     //! Acquire lock
     void lock() {
 #if TBB_USE_ASSERT
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         new(tmp.begin()) scoped_lock(*this);
 #else
   #if _WIN32||_WIN64
         EnterCriticalSection(&impl);
   #else
-        pthread_mutex_lock(&impl);
+        int error_code = pthread_mutex_lock(&impl);
+        if( error_code )
+            tbb::internal::handle_perror(error_code,"recursive_mutex: pthread_mutex_lock failed");
   #endif /* _WIN32||_WIN64 */
 #endif /* TBB_USE_ASSERT */
     }
@@ -180,7 +174,7 @@ public:
     /** Return true if lock acquired; false otherwise. */
     bool try_lock() {
 #if TBB_USE_ASSERT
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
 #else        
   #if _WIN32||_WIN64
@@ -194,7 +188,7 @@ public:
     //! Release lock
     void unlock() {
 #if TBB_USE_ASSERT
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         scoped_lock& s = *tmp.begin();
         s.my_mutex = this;
         s.internal_release();
index e0d45264fe2e8b082ccb111da95561ac3290ebc9..f5cd412ecd25580519d51bff6851b0de74608478 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_runtime_loader_H
@@ -33,7 +25,7 @@
     #error Set TBB_PREVIEW_RUNTIME_LOADER to include runtime_loader.h
 #endif
 
-#include "tbb/tbb_stddef.h"
+#include "tbb_stddef.h"
 #include <climits>
 
 #if _MSC_VER
@@ -86,7 +78,7 @@ There are some implications:
         cooperatively, otherwise the second object will report an error.
 
     -   \c runtime_loader objects will not work (correctly) in parallel due to absence of
-        syncronization.
+        synchronization.
 
 */
 
index 27f230e38c889c331b2f29c5020fb655639077c5..3683aa27ffed3ca4fcea9a756a3e9caa60d7dc71 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_scalable_allocator_H
@@ -88,31 +80,115 @@ void __TBB_EXPORTED_FUNC scalable_aligned_free (void* ptr);
     @ingroup memory_allocation */
 size_t __TBB_EXPORTED_FUNC scalable_msize (void* ptr);
 
+/* Results for scalable_allocation_* functions */
+typedef enum {
+    TBBMALLOC_OK,
+    TBBMALLOC_INVALID_PARAM,
+    TBBMALLOC_UNSUPPORTED,
+    TBBMALLOC_NO_MEMORY,
+    TBBMALLOC_NO_EFFECT
+} ScalableAllocationResult;
+
+/* Setting TBB_MALLOC_USE_HUGE_PAGES environment variable to 1 enables huge pages.
+   scalable_allocation_mode call has priority over environment variable. */
+typedef enum {
+    TBBMALLOC_USE_HUGE_PAGES,  /* value turns using huge pages on and off */
+    /* deprecated, kept for backward compatibility only */
+    USE_HUGE_PAGES = TBBMALLOC_USE_HUGE_PAGES,
+    /* try to limit memory consumption value Bytes, clean internal buffers
+       if limit is exceeded, but not prevents from requesting memory from OS */
+    TBBMALLOC_SET_SOFT_HEAP_LIMIT
+} AllocationModeParam;
+
+/** Set TBB allocator-specific allocation modes.
+    @ingroup memory_allocation */
+int __TBB_EXPORTED_FUNC scalable_allocation_mode(int param, intptr_t value);
+
+typedef enum {
+    /* Clean internal allocator buffers for all threads.
+       Returns TBBMALLOC_NO_EFFECT if no buffers cleaned,
+       TBBMALLOC_OK if some memory released from buffers. */
+    TBBMALLOC_CLEAN_ALL_BUFFERS,
+    /* Clean internal allocator buffer for current thread only.
+       Return values same as for TBBMALLOC_CLEAN_ALL_BUFFERS. */
+    TBBMALLOC_CLEAN_THREAD_BUFFERS
+} ScalableAllocationCmd;
+
+/** Call TBB allocator-specific commands.
+    @ingroup memory_allocation */
+int __TBB_EXPORTED_FUNC scalable_allocation_command(int cmd, void *param);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif /* __cplusplus */
 
 #ifdef __cplusplus
 
+//! The namespace rml contains components of low-level memory pool interface.
 namespace rml {
 class MemoryPool;
 
-#define MEM_POLICY_DEFINED 1
 typedef void *(*rawAllocType)(intptr_t pool_id, size_t &bytes);
 typedef int   (*rawFreeType)(intptr_t pool_id, void* raw_ptr, size_t raw_bytes);
 
+/*
+MemPoolPolicy extension must be compatible with such structure fields layout
+
 struct MemPoolPolicy {
     rawAllocType pAlloc;
     rawFreeType  pFree;
     size_t       granularity;   // granularity of pAlloc allocations
-    void        *pReserved;     // reserved for future extensions
-    size_t       szReserved;    // size of pReserved data
+};
+*/
+
+struct MemPoolPolicy {
+    enum {
+        TBBMALLOC_POOL_VERSION = 1
+    };
+
+    rawAllocType pAlloc;
+    rawFreeType  pFree;
+                 // granularity of pAlloc allocations. 0 means default used.
+    size_t       granularity;
+    int          version;
+                 // all memory consumed at 1st pAlloc call and never returned,
+                 // no more pAlloc calls after 1st
+    unsigned     fixedPool : 1,
+                 // memory consumed but returned only at pool termination
+                 keepAllMemory : 1,
+                 reserved : 30;
+
+    MemPoolPolicy(rawAllocType pAlloc_, rawFreeType pFree_,
+                  size_t granularity_ = 0, bool fixedPool_ = false,
+                  bool keepAllMemory_ = false) :
+        pAlloc(pAlloc_), pFree(pFree_), granularity(granularity_), version(TBBMALLOC_POOL_VERSION),
+        fixedPool(fixedPool_), keepAllMemory(keepAllMemory_),
+        reserved(0) {}
 };
 
-MemoryPool *pool_create(intptr_t pool_id, const MemPoolPolicy* memPoolPolicy);
+// enums have same values as appropriate enums from ScalableAllocationResult
+// TODO: use ScalableAllocationResult in pool_create directly
+enum MemPoolError {
+    // pool created successfully
+    POOL_OK = TBBMALLOC_OK,
+    // invalid policy parameters found
+    INVALID_POLICY = TBBMALLOC_INVALID_PARAM,
+     // requested pool policy is not supported by allocator library
+    UNSUPPORTED_POLICY = TBBMALLOC_UNSUPPORTED,
+    // lack of memory during pool creation
+    NO_MEMORY = TBBMALLOC_NO_MEMORY,
+    // action takes no effect
+    NO_EFFECT = TBBMALLOC_NO_EFFECT
+};
+
+MemPoolError pool_create_v1(intptr_t pool_id, const MemPoolPolicy *policy,
+                            rml::MemoryPool **pool);
+
 bool  pool_destroy(MemoryPool* memPool);
 void *pool_malloc(MemoryPool* memPool, size_t size);
 void *pool_realloc(MemoryPool* memPool, void *object, size_t size);
+void *pool_aligned_malloc(MemoryPool* mPool, size_t size, size_t alignment);
+void *pool_aligned_realloc(MemoryPool* mPool, void *ptr, size_t size, size_t alignment);
 bool  pool_reset(MemoryPool* memPool);
 bool  pool_free(MemoryPool *memPool, void *object);
 }
@@ -128,6 +204,9 @@ bool  pool_free(MemoryPool *memPool, void *object);
     #include "tbb_stddef.h"
 #endif
 
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+ #include <utility> // std::forward
+#endif
 
 namespace tbb {
 
@@ -177,7 +256,16 @@ public:
         size_type absolutemax = static_cast<size_type>(-1) / sizeof (value_type);
         return (absolutemax > 0 ? absolutemax : 1);
     }
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+    template<typename U, typename... Args>
+    void construct(U *p, Args&&... args)
+        { ::new((void *)p) U(std::forward<Args>(args)...); }
+#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    void construct( pointer p, value_type&& value ) { ::new((void*)(p)) value_type( std::move( value ) ); }
+#endif
     void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
+#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
     void destroy( pointer p ) {p->~value_type();}
 };
 
@@ -207,7 +295,7 @@ inline bool operator!=( const scalable_allocator<T>&, const scalable_allocator<U
 } // namespace tbb
 
 #if _MSC_VER
-    #if __TBB_BUILD && !defined(__TBBMALLOC_NO_IMPLICIT_LINKAGE)
+    #if (__TBB_BUILD || __TBBMALLOC_BUILD) && !defined(__TBBMALLOC_NO_IMPLICIT_LINKAGE)
         #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1
     #endif
 
index 0d200a1597ab2022151e940e71b5778a701b2c6a..a7ed31be423b3a64ae66f8e3d94ae07915a5fcaf 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_spin_mutex_H
 #include "tbb_stddef.h"
 #include "tbb_machine.h"
 #include "tbb_profiling.h"
+#include "internal/_mutex_padding.h"
 
 namespace tbb {
 
 //! A lock that occupies a single byte.
-/** A spin_mutex is a spin mutex that fits in a single byte.  
-    It should be used only for locking short critical sections 
-    (typically less than 20 instructions) when fairness is not an issue.  
+/** A spin_mutex is a spin mutex that fits in a single byte.
+    It should be used only for locking short critical sections
+    (typically less than 20 instructions) when fairness is not an issue.
     If zero-initialized, the mutex is considered unheld.
     @ingroup synchronization */
-class spin_mutex {
+class spin_mutex : internal::mutex_copy_deprecated_and_disabled {
     //! 0 if lock is released, 1 if lock is acquired.
     __TBB_atomic_flag flag;
 
@@ -61,9 +54,12 @@ public:
     class scoped_lock : internal::no_copy {
     private:
         //! Points to currently held mutex, or NULL if no lock is held.
-        spin_mutex* my_mutex; 
+        spin_mutex* my_mutex;
 
         //! Value to store into spin_mutex::flag to unlock the mutex.
+        /** This variable is no longer used. Instead, 0 and 1 are used to
+            represent that the lock is free and acquired, respectively.
+            We keep the member variable here to ensure backward compatibility */
         __TBB_Flag my_unlock_value;
 
         //! Like acquire, but with ITT instrumentation.
@@ -82,13 +78,14 @@ public:
         scoped_lock() : my_mutex(NULL), my_unlock_value(0) {}
 
         //! Construct and acquire lock on a mutex.
-        scoped_lock( spin_mutex& m ) { 
+        scoped_lock( spin_mutex& m ) : my_unlock_value(0) {
+            internal::suppress_unused_warning(my_unlock_value);
 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
             my_mutex=NULL;
             internal_acquire(m);
 #else
-            my_unlock_value = __TBB_LockByte(m.flag);
             my_mutex=&m;
+            __TBB_LockByte(m.flag);
 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
         }
 
@@ -97,8 +94,8 @@ public:
 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
             internal_acquire(m);
 #else
-            my_unlock_value = __TBB_LockByte(m.flag);
             my_mutex = &m;
+            __TBB_LockByte(m.flag);
 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
         }
 
@@ -109,10 +106,8 @@ public:
             return internal_try_acquire(m);
 #else
             bool result = __TBB_TryLockByte(m.flag);
-            if( result ) {
-                my_unlock_value = 0;
+            if( result )
                 my_mutex = &m;
-            }
             return result;
 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT*/
         }
@@ -122,7 +117,7 @@ public:
 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
             internal_release();
 #else
-            __TBB_UnlockByte(my_mutex->flag, my_unlock_value);
+            __TBB_UnlockByte(my_mutex->flag);
             my_mutex = NULL;
 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
         }
@@ -133,12 +128,13 @@ public:
 #if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
                 internal_release();
 #else
-                __TBB_UnlockByte(my_mutex->flag, my_unlock_value);
+                __TBB_UnlockByte(my_mutex->flag);
 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
             }
         }
     };
 
+    //! Internal constructor with ITT instrumentation.
     void __TBB_EXPORTED_METHOD internal_construct();
 
     // Mutex traits
@@ -151,7 +147,7 @@ public:
     //! Acquire lock
     void lock() {
 #if TBB_USE_THREADING_TOOLS
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         new(tmp.begin()) scoped_lock(*this);
 #else
         __TBB_LockByte(flag);
@@ -162,7 +158,7 @@ public:
     /** Return true if lock acquired; false otherwise. */
     bool try_lock() {
 #if TBB_USE_THREADING_TOOLS
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         return (new(tmp.begin()) scoped_lock)->internal_try_acquire(*this);
 #else
         return __TBB_TryLockByte(flag);
@@ -172,10 +168,9 @@ public:
     //! Release lock
     void unlock() {
 #if TBB_USE_THREADING_TOOLS
-        aligned_space<scoped_lock,1> tmp;
+        aligned_space<scoped_lock> tmp;
         scoped_lock& s = *tmp.begin();
         s.my_mutex = this;
-        s.my_unlock_value = 0;
         s.internal_release();
 #else
         __TBB_store_with_release(flag, 0);
@@ -183,10 +178,35 @@ public:
     }
 
     friend class scoped_lock;
-};
+}; // end of spin_mutex
 
 __TBB_DEFINE_PROFILING_SET_NAME(spin_mutex)
 
 } // namespace tbb
 
+#if ( __TBB_x86_32 || __TBB_x86_64 )
+#include "internal/_x86_eliding_mutex_impl.h"
+#endif
+
+namespace tbb {
+//! A cross-platform spin mutex with speculative lock acquisition.
+/** On platforms with proper HW support, this lock may speculatively execute
+    its critical sections, using HW mechanisms to detect real data races and
+    ensure atomicity of the critical sections. In particular, it uses
+    Intel(R) Transactional Synchronization Extensions (Intel(R) TSX).
+    Without such HW support, it behaves like a spin_mutex.
+    It should be used for locking short critical sections where the lock is
+    contended but the data it protects are not.  If zero-initialized, the
+    mutex is considered unheld.
+    @ingroup synchronization */
+
+#if ( __TBB_x86_32 || __TBB_x86_64 )
+typedef interface7::internal::padded_mutex<interface7::internal::x86_eliding_mutex,false> speculative_spin_mutex;
+#else
+typedef interface7::internal::padded_mutex<spin_mutex,false> speculative_spin_mutex;
+#endif
+__TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_mutex)
+
+} // namespace tbb
+
 #endif /* __TBB_spin_mutex_H */
index cfe806e9857c9eb290766e5f2c138bfbf529ce10..61151c17925c128ea4694d39ab053048e6777d58 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_spin_rw_mutex_H
 #include "tbb_stddef.h"
 #include "tbb_machine.h"
 #include "tbb_profiling.h"
+#include "internal/_mutex_padding.h"
 
 namespace tbb {
 
+#if __TBB_TSX_AVAILABLE
+namespace interface8 { namespace internal {
+    class x86_rtm_rw_mutex;
+}}
+#endif
+
 class spin_rw_mutex_v3;
 typedef spin_rw_mutex_v3 spin_rw_mutex;
 
 //! Fast, unfair, spinning reader-writer lock with backoff and writer-preference
 /** @ingroup synchronization */
-class spin_rw_mutex_v3 {
+class spin_rw_mutex_v3 : internal::mutex_copy_deprecated_and_disabled {
     //! @cond INTERNAL
 
     //! Internal acquire write lock.
     bool __TBB_EXPORTED_METHOD internal_acquire_writer();
 
-    //! Out of line code for releasing a write lock.  
-    /** This code is has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */
+    //! Out of line code for releasing a write lock.
+    /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */
     void __TBB_EXPORTED_METHOD internal_release_writer();
 
     //! Internal acquire read lock.
@@ -56,8 +55,8 @@ class spin_rw_mutex_v3 {
     //! Internal upgrade reader to become a writer.
     bool __TBB_EXPORTED_METHOD internal_upgrade();
 
-    //! Out of line code for downgrading a writer to a reader.   
-    /** This code is has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */
+    //! Out of line code for downgrading a writer to a reader.
+    /** This code has debug checking and instrumentation for Intel(R) Thread Checker and Intel(R) Thread Profiler. */
     void __TBB_EXPORTED_METHOD internal_downgrade();
 
     //! Internal release read lock.
@@ -89,6 +88,12 @@ public:
     /** It helps to avoid the common problem of forgetting to release lock.
         It also nicely provides the "node" for queuing locks. */
     class scoped_lock : internal::no_copy {
+#if __TBB_TSX_AVAILABLE
+        friend class tbb::interface8::internal::x86_rtm_rw_mutex;
+        // helper methods for x86_rtm_rw_mutex
+        spin_rw_mutex *internal_get_mutex() const { return mutex; }
+        void internal_set_mutex(spin_rw_mutex* m) { mutex = m; }
+#endif
     public:
         //! Construct lock that has not acquired a mutex.
         /** Equivalent to zero-initialization of *this. */
@@ -107,18 +112,18 @@ public:
         //! Acquire lock on given mutex.
         void acquire( spin_rw_mutex& m, bool write = true ) {
             __TBB_ASSERT( !mutex, "holding mutex already" );
-            is_writer = write; 
+            is_writer = write;
             mutex = &m;
             if( write ) mutex->internal_acquire_writer();
             else        mutex->internal_acquire_reader();
         }
 
         //! Upgrade reader to become a writer.
-        /** Returns true if the upgrade happened without re-acquiring the lock and false if opposite */
+        /** Returns whether the upgrade happened without releasing and re-acquiring the lock */
         bool upgrade_to_writer() {
             __TBB_ASSERT( mutex, "lock is not acquired" );
             __TBB_ASSERT( !is_writer, "not a reader" );
-            is_writer = true; 
+            is_writer = true;
             return mutex->internal_upgrade();
         }
 
@@ -138,15 +143,14 @@ public:
 
         //! Downgrade writer to become a reader.
         bool downgrade_to_reader() {
-#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
             __TBB_ASSERT( mutex, "lock is not acquired" );
             __TBB_ASSERT( is_writer, "not a writer" );
+#if TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT
             mutex->internal_downgrade();
 #else
             __TBB_FetchAndAddW( &mutex->state, ((intptr_t)ONE_READER-WRITER));
 #endif /* TBB_USE_THREADING_TOOLS||TBB_USE_ASSERT */
             is_writer = false;
-
             return true;
         }
 
@@ -163,6 +167,7 @@ public:
         }
 
     protected:
+
         //! The pointer to the current mutex that is held, or NULL if no mutex is held.
         spin_rw_mutex* mutex;
 
@@ -205,7 +210,7 @@ public:
     /** Return true if reader lock acquired; false otherwise. */
     bool try_lock_read() {return internal_try_acquire_reader();}
 
-private:
+protected:
     typedef intptr_t state_t;
     static const state_t WRITER = 1;
     static const state_t WRITER_PENDING = 2;
@@ -218,6 +223,7 @@ private:
         Bit 2..N = number of readers holding lock */
     state_t state;
 
+private:
     void __TBB_EXPORTED_METHOD internal_construct();
 };
 
@@ -225,4 +231,29 @@ __TBB_DEFINE_PROFILING_SET_NAME(spin_rw_mutex)
 
 } // namespace tbb
 
+#if __TBB_TSX_AVAILABLE
+#include "internal/_x86_rtm_rw_mutex_impl.h"
+#endif
+
+namespace tbb {
+namespace interface8 {
+//! A cross-platform spin reader/writer mutex with speculative lock acquisition.
+/** On platforms with proper HW support, this lock may speculatively execute
+    its critical sections, using HW mechanisms to detect real data races and
+    ensure atomicity of the critical sections. In particular, it uses
+    Intel(R) Transactional Synchronization Extensions (Intel(R) TSX).
+    Without such HW support, it behaves like a spin_rw_mutex.
+    It should be used for locking short critical sections where the lock is 
+    contended but the data it protects are not.
+    @ingroup synchronization */
+#if __TBB_TSX_AVAILABLE
+typedef interface7::internal::padded_mutex<tbb::interface8::internal::x86_rtm_rw_mutex,true> speculative_spin_rw_mutex;
+#else
+typedef interface7::internal::padded_mutex<tbb::spin_rw_mutex,true> speculative_spin_rw_mutex;
+#endif
+}  // namespace interface8
+
+using interface8::speculative_spin_rw_mutex;
+__TBB_DEFINE_PROFILING_SET_NAME(speculative_spin_rw_mutex)
+} // namespace tbb
 #endif /* __TBB_spin_rw_mutex_H */
index a887431e556be1466d1efd017fe6eada32ca5c23..5dabcd97a23a2100db0da01acbdb09333e3ee606 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_task_H
@@ -39,10 +31,7 @@ namespace tbb {
 
 class task;
 class task_list;
-
-#if __TBB_TASK_GROUP_CONTEXT
 class task_group_context;
-#endif /* __TBB_TASK_GROUP_CONTEXT */
 
 // MSVC does not allow taking the address of a member that was defined
 // privately in task_base and made public in class task via a using declaration.
@@ -52,7 +41,7 @@ class task_group_context;
 #define __TBB_TASK_BASE_ACCESS private
 #endif
 
-namespace internal {
+namespace internal { //< @cond INTERNAL
 
     class allocate_additional_child_of_proxy: no_assign {
         //! No longer used, but retained for binary layout compatibility.  Always NULL.
@@ -64,7 +53,8 @@ namespace internal {
         void __TBB_EXPORTED_METHOD free( task& ) const;
     };
 
-}
+    struct cpu_ctl_env_space { int space[sizeof(internal::uint64_t)/sizeof(int)]; };
+} //< namespace internal @endcond
 
 namespace interface5 {
     namespace internal {
@@ -244,6 +234,7 @@ namespace internal {
         //! Miscellaneous state that is not directly visible to users, stored as a byte for compactness.
         /** 0x0 -> version 1.0 task
             0x1 -> version >=2.1 task
+            0x10 -> task was enqueued
             0x20 -> task_proxy
             0x40 -> task has live ref_count
             0x80 -> a stolen task */
@@ -285,6 +276,7 @@ enum priority_t {
 #endif /* !TBB_USE_CAPTURED_EXCEPTION */
 
 class task_scheduler_init;
+namespace interface7 { class task_arena; }
 
 //! Used to form groups of tasks
 /** @ingroup task_scheduling
@@ -300,8 +292,8 @@ class task_scheduler_init;
 
     The context can be bound to another one, and other contexts can be bound to it,
     forming a tree-like structure: parent -> this -> children. Arrows here designate
-    cancellation propagation direction. If a task in a cancellation group is canceled
-    all the other tasks in this group and groups bound to it (as children) get canceled too.
+    cancellation propagation direction. If a task in a cancellation group is cancelled
+    all the other tasks in this group and groups bound to it (as children) get cancelled too.
 
     IMPLEMENTATION NOTE:
     When adding new members to task_group_context or changing types of existing ones,
@@ -311,6 +303,7 @@ class task_group_context : internal::no_copy {
 private:
     friend class internal::generic_scheduler;
     friend class task_scheduler_init;
+    friend class interface7::task_arena;
 
 #if TBB_USE_CAPTURED_EXCEPTION
     typedef tbb_exception exception_container_type;
@@ -332,6 +325,9 @@ public:
 
     enum traits_type {
         exact_exception = 0x0001ul << traits_offset,
+#if __TBB_FP_CONTEXT
+        fp_settings     = 0x0002ul << traits_offset,
+#endif
         concurrent_wait = 0x0004ul << traits_offset,
 #if TBB_USE_CAPTURED_EXCEPTION
         default_traits = 0
@@ -342,12 +338,15 @@ public:
 
 private:
     enum state {
-        may_have_children = 1
+        may_have_children = 1,
+        // the following enumerations must be the last, new 2^x values must go above
+        next_state_value, low_unused_state_bit = (next_state_value-1)*2
     };
 
     union {
         //! Flavor of this context: bound or isolated.
-        kind_type my_kind;
+        // TODO: describe asynchronous use, and whether any memory semantics are needed
+        __TBB_atomic kind_type my_kind;
         uintptr_t _my_kind_aligner;
     };
 
@@ -368,16 +367,27 @@ private:
         line with a local variable that is frequently written to. **/
     char _leading_padding[internal::NFS_MaxLineSize
                           - 2 * sizeof(uintptr_t)- sizeof(void*) - sizeof(internal::context_list_node_t)
-                          - sizeof(__itt_caller)];
+                          - sizeof(__itt_caller)
+#if __TBB_FP_CONTEXT
+                          - sizeof(internal::cpu_ctl_env_space)
+#endif
+                         ];
 
-    //! Specifies whether cancellation was request for this task group.
+#if __TBB_FP_CONTEXT
+    //! Space for platform-specific FPU settings.
+    /** Must only be accessed inside TBB binaries, and never directly in user
+        code or inline methods. */
+    internal::cpu_ctl_env_space my_cpu_ctl_env;
+#endif
+
+    //! Specifies whether cancellation was requested for this task group.
     uintptr_t my_cancellation_requested;
 
     //! Version for run-time checks and behavioral traits of the context.
     /** Version occupies low 16 bits, and traits (zero or more ORed enumerators
         from the traits_type enumerations) take the next 16 bits.
         Original (zeroth) version of the context did not support any traits. **/
-    uintptr_t  my_version_and_traits;
+    uintptr_t my_version_and_traits;
 
     //! Pointer to the container storing exception being propagated across this task group.
     exception_container_type *my_exception;
@@ -385,7 +395,7 @@ private:
     //! Scheduler instance that registered this context in its thread specific list.
     internal::generic_scheduler *my_owner;
 
-    //! Internal state (combination of state flags).
+    //! Internal state (combination of state flags, currently only may_have_children).
     uintptr_t my_state;
 
 #if __TBB_TASK_PRIORITY
@@ -414,7 +424,7 @@ public:
 
         Creating isolated contexts involve much less overhead, but they have limited
         utility. Normally when an exception occurs in an algorithm that has nested
-        ones running, it is desirably to have all the nested algorithms canceled
+        ones running, it is desirably to have all the nested algorithms cancelled
         as well. Such a behavior requires nested algorithms to use bound contexts.
 
         There is one good place where using isolated algorithms is beneficial. It is
@@ -434,11 +444,12 @@ public:
     task_group_context ( kind_type relation_with_parent = bound,
                          uintptr_t traits = default_traits )
         : my_kind(relation_with_parent)
-        , my_version_and_traits(1 | traits)
+        , my_version_and_traits(2 | traits)
     {
         init();
     }
 
+    // Do not introduce standalone unbind method since it will break state propagation assumptions
     __TBB_EXPORTED_METHOD ~task_group_context ();
 
     //! Forcefully reinitializes the context after the task tree it was associated with is completed.
@@ -466,15 +477,27 @@ public:
 
     //! Records the pending exception, and cancels the task group.
     /** May be called only from inside a catch-block. If the context is already
-        canceled, does nothing.
+        cancelled, does nothing.
         The method brings the task group associated with this context exactly into
         the state it would be in, if one of its tasks threw the currently pending
         exception during its execution. In other words, it emulates the actions
         of the scheduler's dispatch loop exception handler. **/
     void __TBB_EXPORTED_METHOD register_pending_exception ();
 
+#if __TBB_FP_CONTEXT
+    //! Captures the current FPU control settings to the context.
+    /** Because the method assumes that all the tasks that used to be associated with
+        this context have already finished, calling it while the context is still
+        in use somewhere in the task hierarchy leads to undefined behavior.
+
+        IMPORTANT: This method is not thread safe!
+
+        The method does not change the FPU control settings of the context's parent. **/
+    void __TBB_EXPORTED_METHOD capture_fp_settings ();
+#endif
+
 #if __TBB_TASK_PRIORITY
-    //! Changes priority of the task grop
+    //! Changes priority of the task group
     void set_priority ( priority_t );
 
     //! Retrieves current priority of the current task group
@@ -495,14 +518,9 @@ private:
     static const kind_type detached = kind_type(binding_completed+1);
     static const kind_type dying = kind_type(detached+1);
 
-    //! Propagates state change (if any) from an ancestor
-    /** Checks if one of this object's ancestors is in a new state, and propagates
-        the new state to all its descendants in this object's heritage line. **/
+    //! Propagates any state change detected to *this, and as an optimisation possibly also upward along the heritage line.
     template <typename T>
-    void propagate_state_from_ancestors ( T task_group_context::*mptr_state, T new_state );
-
-    //! Makes sure that the context is registered with a scheduler instance.
-    inline void finish_initialization ( internal::generic_scheduler *local_sched );
+    void propagate_task_group_state ( T task_group_context::*mptr_state, task_group_context& src, T new_state );
 
     //! Registers this context with the local scheduler and binds it to its parent context
     void bind_to ( internal::generic_scheduler *local_sched );
@@ -510,6 +528,11 @@ private:
     //! Registers this context with the local scheduler
     void register_with ( internal::generic_scheduler *local_sched );
 
+#if __TBB_FP_CONTEXT
+    //! Copies FPU control setting from another context
+    // TODO: Consider adding #else stub in order to omit #if sections in other code
+    void copy_fp_settings( const task_group_context &src );
+#endif /* __TBB_FP_CONTEXT */
 }; // class task_group_context
 
 #endif /* __TBB_TASK_GROUP_CONTEXT */
@@ -549,6 +572,10 @@ public:
         freed,
         //! task to be recycled as continuation
         recycle
+#if __TBB_RECYCLE_TO_ENQUEUE
+        //! task to be scheduled for starvation-resistant execution
+        ,to_enqueue
+#endif
     };
 
     //------------------------------------------------------------------------
@@ -640,12 +667,14 @@ public:
         prefix().state = reexecute;
     }
 
-    // All depth-related methods are obsolete, and are retained for the sake
-    // of backward source compatibility only
-    intptr_t depth() const {return 0;}
-    void set_depth( intptr_t ) {}
-    void add_to_depth( int ) {}
-
+#if __TBB_RECYCLE_TO_ENQUEUE
+    //! Schedule this to enqueue after descendant tasks complete.
+    /** Save enqueue/spawn difference, it has the semantics of recycle_as_safe_continuation. */
+    void recycle_to_enqueue() {
+        __TBB_ASSERT( prefix().state==executing, "execute not running, or already recycled" );
+        prefix().state = to_enqueue;
+    }
+#endif /* __TBB_RECYCLE_TO_ENQUEUE */
 
     //------------------------------------------------------------------------
     // Spawning and blocking
@@ -816,6 +845,8 @@ public:
 
     //! Returns true if the context has received cancellation request.
     bool is_cancelled () const { return prefix().context->is_group_execution_cancelled(); }
+#else
+    bool is_cancelled () const { return false; }
 #endif /* __TBB_TASK_GROUP_CONTEXT */
 
 #if __TBB_TASK_PRIORITY
@@ -854,6 +885,21 @@ class empty_task: public task {
     }
 };
 
+//! @cond INTERNAL
+namespace internal {
+    template<typename F>
+    class function_task : public task {
+        F my_func;
+        /*override*/ task* execute() {
+            my_func();
+            return NULL;
+        }
+    public:
+        function_task( const F& f ) : my_func(f) {}
+    };
+} // namespace internal
+//! @endcond
+
 //! A list of children.
 /** Used for method task::spawn_children
     @ingroup task_scheduling */
diff --git a/dependencies64/tbb/include/tbb/task_arena.h b/dependencies64/tbb/include/tbb/task_arena.h
new file mode 100644 (file)
index 0000000..893763e
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
+*/
+
+#ifndef __TBB_task_arena_H
+#define __TBB_task_arena_H
+
+#include "task.h"
+#include "tbb_exception.h"
+#if TBB_USE_THREADING_TOOLS
+#include "atomic.h" // for as_atomic
+#endif
+
+#if __TBB_TASK_ARENA
+
+namespace tbb {
+
+//! @cond INTERNAL
+namespace internal {
+    //! Internal to library. Should not be used by clients.
+    /** @ingroup task_scheduling */
+    class arena;
+    class task_scheduler_observer_v3;
+} // namespace internal
+//! @endcond
+
+namespace interface7 {
+//! @cond INTERNAL
+namespace internal {
+using namespace tbb::internal; //e.g. function_task from task.h
+
+class delegate_base : no_assign {
+public:
+    virtual void operator()() const = 0;
+    virtual ~delegate_base() {}
+};
+
+template<typename F>
+class delegated_function : public delegate_base {
+    F &my_func;
+    /*override*/ void operator()() const {
+        my_func();
+    }
+public:
+    delegated_function ( F& f ) : my_func(f) {}
+};
+
+class task_arena_base {
+protected:
+    //! NULL if not currently initialized.
+    internal::arena* my_arena;
+
+#if __TBB_TASK_GROUP_CONTEXT
+    //! default context of the arena
+    task_group_context *my_context;
+#endif
+
+    //! Concurrency level for deferred initialization
+    int my_max_concurrency;
+
+    //! Reserved master slots
+    unsigned my_master_slots;
+
+    //! Special settings
+    intptr_t my_version_and_traits;
+
+    enum {
+        default_flags = 0
+#if __TBB_TASK_GROUP_CONTEXT
+        | (task_group_context::default_traits & task_group_context::exact_exception)  // 0 or 1 << 16
+        , exact_exception_flag = task_group_context::exact_exception // used to specify flag for context directly
+#endif
+    };
+
+    task_arena_base(int max_concurrency, unsigned reserved_for_masters)
+        : my_arena(0)
+#if __TBB_TASK_GROUP_CONTEXT
+        , my_context(0)
+#endif
+        , my_max_concurrency(max_concurrency)
+        , my_master_slots(reserved_for_masters)
+        , my_version_and_traits(default_flags)
+        {}
+
+    void __TBB_EXPORTED_METHOD internal_initialize( );
+    void __TBB_EXPORTED_METHOD internal_terminate( );
+    void __TBB_EXPORTED_METHOD internal_enqueue( task&, intptr_t ) const;
+    void __TBB_EXPORTED_METHOD internal_execute( delegate_base& ) const;
+    void __TBB_EXPORTED_METHOD internal_wait() const;
+    static int __TBB_EXPORTED_FUNC internal_current_slot();
+public:
+    //! Typedef for number of threads that is automatic.
+    static const int automatic = -1; // any value < 1 means 'automatic'
+
+};
+
+} // namespace internal
+//! @endcond
+
+/** 1-to-1 proxy representation class of scheduler's arena
+ * Constructors set up settings only, real construction is deferred till the first method invocation
+ * Destructor only removes one of the references to the inner arena representation.
+ * Final destruction happens when all the references (and the work) are gone.
+ */
+class task_arena : public internal::task_arena_base {
+    friend class tbb::internal::task_scheduler_observer_v3;
+    bool my_initialized;
+
+public:
+    //! Creates task_arena with certain concurrency limits
+    /** Sets up settings only, real construction is deferred till the first method invocation
+     *  @arg max_concurrency specifies total number of slots in arena where threads work
+     *  @arg reserved_for_masters specifies number of slots to be used by master threads only.
+     *       Value of 1 is default and reflects behavior of implicit arenas.
+     **/
+    task_arena(int max_concurrency = automatic, unsigned reserved_for_masters = 1)
+        : task_arena_base(max_concurrency, reserved_for_masters)
+        , my_initialized(false)
+    {}
+
+    //! Copies settings from another task_arena
+    task_arena(const task_arena &s) // copy settings but not the reference or instance
+        : task_arena_base(s.my_max_concurrency, s.my_master_slots)
+        , my_initialized(false)
+    {}
+
+    //! Forces allocation of the resources for the task_arena as specified in constructor arguments
+    inline void initialize() {
+        if( !my_initialized ) {
+            internal_initialize();
+#if TBB_USE_THREADING_TOOLS
+            // Threading tools respect lock prefix but report false-positive data-race via plain store
+            internal::as_atomic(my_initialized).fetch_and_store<release>(true);
+#else
+            my_initialized = true;
+#endif //TBB_USE_THREADING_TOOLS
+        }
+    }
+
+    //! Overrides concurrency level and forces initialization of internal representation
+    inline void initialize(int max_concurrency, unsigned reserved_for_masters = 1) {
+        __TBB_ASSERT( !my_arena, "Impossible to modify settings of an already initialized task_arena");
+        if( !my_initialized ) {
+            my_max_concurrency = max_concurrency;
+            my_master_slots = reserved_for_masters;
+            initialize();
+        }
+    }
+
+    //! Removes the reference to the internal arena representation.
+    //! Not thread safe wrt concurrent invocations of other methods.
+    inline void terminate() {
+        if( my_initialized ) {
+            internal_terminate();
+            my_initialized = false;
+        }
+    }
+
+    //! Removes the reference to the internal arena representation, and destroys the external object.
+    //! Not thread safe wrt concurrent invocations of other methods.
+    ~task_arena() {
+        terminate();
+    }
+
+    //! Returns true if the arena is active (initialized); false otherwise.
+    //! The name was chosen to match a task_scheduler_init method with the same semantics.
+    bool is_active() const { return my_initialized; }
+
+    //! Enqueues a task into the arena to process a functor, and immediately returns.
+    //! Does not require the calling thread to join the arena
+    template<typename F>
+    void enqueue( const F& f ) {
+        initialize();
+#if __TBB_TASK_GROUP_CONTEXT
+        __TBB_ASSERT(my_context, NULL);
+        internal_enqueue( *new( task::allocate_root(*my_context) ) internal::function_task<F>(f), 0 );
+#else
+        internal_enqueue( *new( task::allocate_root() ) internal::function_task<F>(f), 0 );
+#endif
+    }
+
+#if __TBB_TASK_PRIORITY
+    //! Enqueues a task with priority p into the arena to process a functor f, and immediately returns.
+    //! Does not require the calling thread to join the arena
+    template<typename F>
+    void enqueue( const F& f, priority_t p ) {
+        __TBB_ASSERT( p == priority_low || p == priority_normal || p == priority_high, "Invalid priority level value" );
+        initialize();
+#if __TBB_TASK_GROUP_CONTEXT
+        internal_enqueue( *new( task::allocate_root(*my_context) ) internal::function_task<F>(f), (intptr_t)p );
+#else
+        internal_enqueue( *new( task::allocate_root() ) internal::function_task<F>(f), (intptr_t)p );
+#endif
+    }
+#endif// __TBB_TASK_PRIORITY
+
+    //! Joins the arena and executes a functor, then returns
+    //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion
+    //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread
+    template<typename F>
+    void execute(F& f) {
+        initialize();
+        internal::delegated_function<F> d(f);
+        internal_execute( d );
+    }
+
+    //! Joins the arena and executes a functor, then returns
+    //! If not possible to join, wraps the functor into a task, enqueues it and waits for task completion
+    //! Can decrement the arena demand for workers, causing a worker to leave and free a slot to the calling thread
+    template<typename F>
+    void execute(const F& f) {
+        initialize();
+        internal::delegated_function<const F> d(f);
+        internal_execute( d );
+    }
+
+#if __TBB_EXTRA_DEBUG
+    //! Wait for all work in the arena to be completed
+    //! Even submitted by other application threads
+    //! Joins arena if/when possible (in the same way as execute())
+    void debug_wait_until_empty() {
+        initialize();
+        internal_wait();
+    }
+#endif //__TBB_EXTRA_DEBUG
+
+    //! Returns the index, aka slot number, of the calling thread in its current arena
+    inline static int current_thread_index() {
+        return internal_current_slot();
+    }
+};
+
+} // namespace interfaceX
+
+using interface7::task_arena;
+
+} // namespace tbb
+
+#endif /* __TBB_TASK_ARENA */
+
+#endif /* __TBB_task_arena_H */
index 2e42544a713344b9b19c82b4b357b1614ab0d11e..4cbe7d55b552b04ec7930e687f4d0de9060934e0 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_task_group_H
@@ -40,9 +32,14 @@ namespace internal {
     template<typename F> class task_handle_task;
 }
 
+class task_group;
+class structured_task_group;
+
 template<typename F>
 class task_handle : internal::no_assign {
     template<typename _F> friend class internal::task_handle_task;
+    friend class task_group;
+    friend class structured_task_group;
 
     static const intptr_t scheduled = 0x1;
 
@@ -69,20 +66,6 @@ enum task_group_status {
 
 namespace internal {
 
-// Suppress gratuitous warnings from icc 11.0 when lambda expressions are used in instances of function_task.
-//#pragma warning(disable: 588)
-
-template<typename F>
-class function_task : public task {
-    F my_func;
-    /*override*/ task* execute() {
-        my_func();
-        return NULL;
-    }
-public:
-    function_task( const F& f ) : my_func(f) {}
-};
-
 template<typename F>
 class task_handle_task : public task {
     task_handle<F>& my_handle;
@@ -125,7 +108,7 @@ public:
         my_root->set_ref_count(1);
     }
 
-    ~task_group_base() {
+    ~task_group_base() __TBB_NOEXCEPT(false) {
         if( my_root->ref_count() > 1 ) {
             bool stack_unwinding_in_progress = std::uncaught_exception();
             // Always attempt to do proper cleanup to avoid inevitable memory corruption 
@@ -181,21 +164,6 @@ class task_group : public internal::task_group_base {
 public:
     task_group () : task_group_base( task_group_context::concurrent_wait ) {}
 
-#if TBB_DEPRECATED
-    ~task_group() __TBB_TRY {
-        __TBB_ASSERT( my_root->ref_count() != 0, NULL );
-        if( my_root->ref_count() > 1 )
-            my_root->wait_for_all();
-    }
-#if TBB_USE_EXCEPTIONS
-    catch (...) {
-        // Have to destroy my_root here as the base class destructor won't be called
-        task::destroy(*my_root);
-        throw;
-    }
-#endif /* TBB_USE_EXCEPTIONS */
-#endif /* TBB_DEPRECATED */
-
 #if __SUNPRO_CC
     template<typename F>
     void run( task_handle<F>& h ) {
@@ -217,6 +185,7 @@ public:
 
     template<typename F>
     task_group_status run_and_wait( task_handle<F>& h ) {
+      h.mark_scheduled();
       return internal_run_and_wait< task_handle<F> >( h );
     }
 }; // class task_group
@@ -225,6 +194,7 @@ class structured_task_group : public internal::task_group_base {
 public:
     template<typename F>
     task_group_status run_and_wait ( task_handle<F>& h ) {
+        h.mark_scheduled();
         return internal_run_and_wait< task_handle<F> >( h );
     }
 
index 576d3702a21438207c2cce8fcfb829f37b7db0f7..b49bddb899ec6d0464e28c105640b08ef5bc0be6 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_task_scheduler_init_H
@@ -64,6 +56,11 @@ class task_scheduler_init: internal::no_copy {
         propagation_mode_captured = 2u,
         propagation_mode_mask = propagation_mode_exact | propagation_mode_captured
     };
+#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
+    enum {
+        wait_workers_in_terminate_flag = 128u
+    };
+#endif
 
     /** NULL if not currently initialized. */
     internal::scheduler* my_scheduler;
@@ -97,7 +94,12 @@ public:
     void __TBB_EXPORTED_METHOD terminate();
 
     //! Shorthand for default constructor followed by call to initialize(number_of_threads).
-    task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0 ) : my_scheduler(NULL)  {
+#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
+    task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0, bool wait_workers_in_terminate = false ) : my_scheduler(NULL)
+#else
+    task_scheduler_init( int number_of_threads=automatic, stack_size_type thread_stack_size=0 ) : my_scheduler(NULL)
+#endif
+    {
         // Two lowest order bits of the stack size argument may be taken to communicate
         // default exception propagation mode of the client to be used when the
         // client manually creates tasks in the master thread and does not use
@@ -109,6 +111,10 @@ public:
 #if TBB_USE_EXCEPTIONS
         thread_stack_size |= TBB_USE_CAPTURED_EXCEPTION ? propagation_mode_captured : propagation_mode_exact;
 #endif /* TBB_USE_EXCEPTIONS */
+#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
+        if (wait_workers_in_terminate)
+            my_scheduler = (internal::scheduler*)wait_workers_in_terminate_flag;
+#endif
         initialize( number_of_threads, thread_stack_size );
     }
 
index 4c09863022709c2617e97da27f3ec5a44b7ab823..6c8ac4da030b449e9162292c42fd813d3b196d93 100644 (file)
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_task_scheduler_observer_H
 #define __TBB_task_scheduler_observer_H
 
 #include "atomic.h"
+#if __TBB_TASK_ARENA
+#include "task_arena.h"
+#endif //__TBB_TASK_ARENA
 
 #if __TBB_SCHEDULER_OBSERVER
 
 namespace tbb {
-
+namespace interface6 {
+class task_scheduler_observer;
+}
 namespace internal {
 
 class observer_proxy;
+class observer_list;
 
 class task_scheduler_observer_v3 {
     friend class observer_proxy;
+    friend class observer_list;
+    friend class interface6::task_scheduler_observer;
+
+    //! Pointer to the proxy holding this observer.
+    /** Observers are proxied by the scheduler to maintain persistent lists of them. **/
     observer_proxy* my_proxy;
+
+    //! Counter preventing the observer from being destroyed while in use by the scheduler.
+    /** Valid only when observation is on. **/
     atomic<intptr_t> my_busy_count;
+
 public:
     //! Enable or disable observation
+    /** For local observers the method can be used only when the current thread
+        has the task scheduler initialized or is attached to an arena.
+
+        Repeated calls with the same state are no-ops. **/
     void __TBB_EXPORTED_METHOD observe( bool state=true );
 
-    //! True if observation is enables; false otherwise.
+    //! Returns true if observation is enabled, false otherwise.
     bool is_observing() const {return my_proxy!=NULL;}
 
     //! Construct observer with observation disabled.
-    task_scheduler_observer_v3() : my_proxy(NULL) {my_busy_count=0;}
+    task_scheduler_observer_v3() : my_proxy(NULL) { my_busy_count.store<relaxed>(0); }
+
+    //! Entry notification
+    /** Invoked from inside observe(true) call and whenever a worker enters the arena 
+        this observer is associated with. If a thread is already in the arena when
+        the observer is activated, the entry notification is called before it
+        executes the first stolen task.
 
-    //! Called by thread before first steal since observation became enabled
+        Obsolete semantics. For global observers it is called by a thread before
+        the first steal since observation became enabled. **/
     virtual void on_scheduler_entry( bool /*is_worker*/ ) {} 
 
-    //! Called by thread when it no longer takes part in task stealing.
+    //! Exit notification
+    /** Invoked from inside observe(false) call and whenever a worker leaves the
+        arena this observer is associated with.
+
+        Obsolete semantics. For global observers it is called by a thread before
+        the first steal since observation became enabled. **/
     virtual void on_scheduler_exit( bool /*is_worker*/ ) {}
 
-    //! Destructor
-    virtual ~task_scheduler_observer_v3() {observe(false);}
+    //! Destructor automatically switches observation off if it is enabled.
+    virtual ~task_scheduler_observer_v3() { if(my_proxy) observe(false);}
 };
 
 } // namespace internal
 
-typedef internal::task_scheduler_observer_v3 task_scheduler_observer;
+#if __TBB_ARENA_OBSERVER
+namespace interface6 {
+class task_scheduler_observer : public internal::task_scheduler_observer_v3 {
+    friend class internal::task_scheduler_observer_v3;
+    friend class internal::observer_proxy;
+    friend class internal::observer_list;
+
+    /** Negative numbers with the largest absolute value to minimize probability
+        of coincidence in case of a bug in busy count usage. **/
+    // TODO: take more high bits for version number
+    static const intptr_t v6_trait = (intptr_t)((~(uintptr_t)0 >> 1) + 1);
+
+    //! contains task_arena pointer or tag indicating local or global semantics of the observer
+    intptr_t my_context_tag;
+    enum { global_tag = 0, implicit_tag = 1 };
+
+public:
+    //! Construct local or global observer in inactive state (observation disabled).
+    /** For a local observer entry/exit notifications are invoked whenever a worker
+        thread joins/leaves the arena of the observer's owner thread. If a thread is
+        already in the arena when the observer is activated, the entry notification is
+        called before it executes the first stolen task. **/
+    /** TODO: Obsolete.
+        Global observer semantics is obsolete as it violates master thread isolation
+        guarantees and is not composable. Thus the current default behavior of the
+        constructor is obsolete too and will be changed in one of the future versions
+        of the library. **/
+    task_scheduler_observer( bool local = false ) {
+        my_context_tag = local? implicit_tag : global_tag;
+    }
+
+#if __TBB_TASK_ARENA
+    //! Construct local observer for a given arena in inactive state (observation disabled).
+    /** entry/exit notifications are invoked whenever a thread joins/leaves arena.
+        If a thread is already in the arena when the observer is activated, the entry notification
+        is called before it executes the first stolen task. **/
+    task_scheduler_observer( task_arena & a) {
+        my_context_tag = (intptr_t)&a;
+    }
+#endif //__TBB_TASK_ARENA
+
+    /** Destructor protects instance of the observer from concurrent notification.
+       It is recommended to disable observation before destructor of a derived class starts,
+       otherwise it can lead to concurrent notification callback on partly destroyed object **/
+    virtual ~task_scheduler_observer() { if(my_proxy) observe(false); }
+
+    //! Enable or disable observation
+    /** Warning: concurrent invocations of this method are not safe.
+        Repeated calls with the same state are no-ops. **/
+    void observe( bool state=true ) {
+        if( state && !my_proxy ) {
+            __TBB_ASSERT( !my_busy_count, "Inconsistent state of task_scheduler_observer instance");
+            my_busy_count.store<relaxed>(v6_trait);
+        }
+        internal::task_scheduler_observer_v3::observe(state);
+    }
+
+    //! Return commands for may_sleep()
+    enum { keep_awake = false, allow_sleep = true };
+
+    //! The callback can be invoked by a worker thread before it goes to sleep.
+    /** If it returns false ('keep_awake'), the thread will keep spinning and looking for work.
+        It will not be called for master threads. **/
+    virtual bool may_sleep() { return allow_sleep; }
+};
+
+} //namespace interface6
+using interface6::task_scheduler_observer;
+#else /*__TBB_ARENA_OBSERVER*/
+typedef tbb::internal::task_scheduler_observer_v3 task_scheduler_observer;
+#endif /*__TBB_ARENA_OBSERVER*/
 
 } // namespace tbb
 
index 259d1dfef3ace124d7e96bb30f71c9b7a1103abf..8a8a8dfa80fd0a016aa08972f617616a3ec4afa1 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
 
-    This file is part of Threading Building Blocks.
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
 
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tbb_H
@@ -37,6 +29,9 @@
     Any header listed below can be included independently of others.
 **/
 
+#if TBB_PREVIEW_AGGREGATOR
+#include "aggregator.h"
+#endif
 #include "aligned_space.h"
 #include "atomic.h"
 #include "blocked_range.h"
 #include "blocked_range3d.h"
 #include "cache_aligned_allocator.h"
 #include "combinable.h"
-#include "concurrent_unordered_map.h"
 #include "concurrent_hash_map.h"
+#if TBB_PREVIEW_CONCURRENT_LRU_CACHE
+#include "concurrent_lru_cache.h"
+#endif
+#include "concurrent_priority_queue.h"
 #include "concurrent_queue.h"
+#include "concurrent_unordered_map.h"
+#include "concurrent_unordered_set.h"
 #include "concurrent_vector.h"
 #include "critical_section.h"
 #include "enumerable_thread_specific.h"
+#include "flow_graph.h"
 #include "mutex.h"
 #include "null_mutex.h"
 #include "null_rw_mutex.h"
 #include "queuing_mutex.h"
 #include "queuing_rw_mutex.h"
 #include "reader_writer_lock.h"
-#if TBB_PREVIEW_CONCURRENT_PRIORITY_QUEUE
-#include "concurrent_priority_queue.h"
-#endif
 #include "recursive_mutex.h"
 #include "spin_mutex.h"
 #include "spin_rw_mutex.h"
 #include "task.h"
+#include "task_arena.h"
 #include "task_group.h"
 #include "task_scheduler_init.h"
 #include "task_scheduler_observer.h"
index bb4690e98c495f080831d47b054009dfdf7df5b8..d9480f2adfb75006c2a707227fa9534c36999406 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tbb_allocator_H
@@ -31,6 +23,9 @@
 
 #include "tbb_stddef.h"
 #include <new>
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+ #include <utility> // std::forward
+#endif
 
 #if !TBB_USE_EXCEPTIONS && _MSC_VER
     // Suppress "C++ exception handler used, but unwind semantics are not enabled" warning in STL headers
@@ -118,7 +113,16 @@ public:
     }
     
     //! Copy-construct value at location pointed to by p.
+#if __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+    template<typename U, typename... Args>
+    void construct(U *p, Args&&... args)
+        { ::new((void *)p) U(std::forward<Args>(args)...); }
+#else // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+    void construct( pointer p, value_type&& value ) {::new((void*)(p)) value_type(std::move(value));}
+#endif
     void construct( pointer p, const value_type& value ) {::new((void*)(p)) value_type(value);}
+#endif // __TBB_ALLOCATOR_CONSTRUCT_VARIADIC
 
     //! Destroy value at location pointed to by p.
     void destroy( pointer p ) {p->~value_type();}
index 3b7c737f3427f576c6cf6a46b6aae9735826c52b..fad3400cefc92360aab70ee61cf163532d19cb0b 100644 (file)
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tbb_config_H
 #define __TBB_tbb_config_H
 
 /** This header is supposed to contain macro definitions and C style comments only.
-    The macros defined here are intended to control such aspects of TBB build as 
+    The macros defined here are intended to control such aspects of TBB build as
     - presence of compiler features
     - compilation modes
     - feature sets
     - known compiler/platform issues
 **/
 
+/*Check which standard library we use on OS X.*/
+/*__TBB_SYMBOL is defined only while processing exported symbols list where C++ is not allowed.*/
+#if !defined(__TBB_SYMBOL) && __APPLE__
+    #include <cstddef>
+#endif
+
+// note that when ICC is in use __TBB_GCC_VERSION might not closely match GCC version on the machine
 #define __TBB_GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
 
+#if __clang__
+    /**according to clang documentation version can be vendor specific **/
+    #define __TBB_CLANG_VERSION (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__)
+#endif
+
+/** Preprocessor symbols to determine HW architecture **/
+
+#if _WIN32||_WIN64
+#   if defined(_M_X64)||defined(__x86_64__)  // the latter for MinGW support
+#       define __TBB_x86_64 1
+#   elif defined(_M_IA64)
+#       define __TBB_ipf 1
+#   elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support
+#       define __TBB_x86_32 1
+#   else
+#       define __TBB_generic_arch 1
+#   endif
+#else /* Assume generic Unix */
+#   if !__linux__ && !__APPLE__
+#       define __TBB_generic_os 1
+#   endif
+#   if __x86_64__
+#       define __TBB_x86_64 1
+#   elif __ia64__
+#       define __TBB_ipf 1
+#   elif __i386__||__i386  // __i386 is for Sun OS
+#       define __TBB_x86_32 1
+#   else
+#       define __TBB_generic_arch 1
+#   endif
+#endif
+
+#if __MIC__ || __MIC2__
+#define __TBB_DEFINE_MIC 1
+#endif
+
+#define __TBB_TSX_AVAILABLE  (__TBB_x86_32 || __TBB_x86_64) && !__TBB_DEFINE_MIC
+
 /** Presence of compiler features **/
 
-#if (__TBB_GCC_VERSION >= 40400) && !defined(__INTEL_COMPILER)
+#if __INTEL_COMPILER == 9999 && __INTEL_COMPILER_BUILD_DATE == 20110811
+/* Intel(R) Composer XE 2011 Update 6 incorrectly sets __INTEL_COMPILER. Fix it. */
+    #undef __INTEL_COMPILER
+    #define __INTEL_COMPILER 1210
+#endif
+
+#if __TBB_GCC_VERSION >= 40400 && !defined(__INTEL_COMPILER)
     /** warning suppression pragmas available in GCC since 4.4 **/
     #define __TBB_GCC_WARNING_SUPPRESSION_PRESENT 1
 #endif
 
-/* TODO: The following condition should be extended when new compilers/runtimes 
-         with std::exception_ptr support appear. */
-#define __TBB_EXCEPTION_PTR_PRESENT  ((_MSC_VER >= 1600 || (__GXX_EXPERIMENTAL_CXX0X__ && __GNUC__==4 && __GNUC_MINOR__>=4)) && !__INTEL_COMPILER)
+/* Select particular features of C++11 based on compiler version.
+   ICC 12.1 (Linux), GCC 4.3 and higher, clang 2.9 and higher
+   set __GXX_EXPERIMENTAL_CXX0X__ in c++11 mode.
+
+   Compilers that mimics other compilers (ICC, clang) must be processed before
+   compilers they mimic (GCC, MSVC).
+
+   TODO: The following conditions should be extended when new compilers/runtimes
+   support added.
+ */
+
+#if __INTEL_COMPILER
+    /** C++11 mode detection macros for Intel C++ compiler (enabled by -std=c++0x option):
+          __INTEL_CXX11_MODE__ for version >=13.0
+          __STDC_HOSTED__ for version >=12.0 on Windows,
+          __GXX_EXPERIMENTAL_CXX0X__ for version >=12.0 on Linux and OS X. **/
+    //  On Windows, C++11 features supported by Visual Studio 2010 and higher are enabled by default
+    #ifndef __INTEL_CXX11_MODE__
+        #define __INTEL_CXX11_MODE__ ((_MSC_VER && __STDC_HOSTED__) || __GXX_EXPERIMENTAL_CXX0X__)
+        // TODO: check if more conditions can be simplified with the above macro
+    #endif
+    #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT    (__INTEL_CXX11_MODE__ && __VARIADIC_TEMPLATES)
+    // Both r-value reference support in compiler and std::move/std::forward
+    // presence in C++ standard library is checked.
+    #define __TBB_CPP11_RVALUE_REF_PRESENT            ((__GXX_EXPERIMENTAL_CXX0X__ && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION) || _MSC_VER >= 1600) && __INTEL_COMPILER >= 1200)
+    #if  _MSC_VER >= 1600
+        #define __TBB_EXCEPTION_PTR_PRESENT           ( __INTEL_COMPILER > 1300                                                \
+                                                      /*ICC 12.1 Upd 10 and 13 beta Upd 2 fixed exception_ptr linking  issue*/ \
+                                                      || (__INTEL_COMPILER == 1300 && __INTEL_COMPILER_BUILD_DATE >= 20120530) \
+                                                      || (__INTEL_COMPILER == 1210 && __INTEL_COMPILER_BUILD_DATE >= 20120410) )
+    /** libstdc++ that comes with GCC 4.6 use C++11 features not supported by ICC 12.1.
+     *  Because of that ICC 12.1 does not support C++11 mode with with gcc 4.6 (or higher),
+     *  and therefore does not  define __GXX_EXPERIMENTAL_CXX0X__ macro **/
+    #elif __TBB_GCC_VERSION >= 40404 && __TBB_GCC_VERSION < 40600
+        #define __TBB_EXCEPTION_PTR_PRESENT           (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1200)
+    #elif __TBB_GCC_VERSION >= 40600
+        #define __TBB_EXCEPTION_PTR_PRESENT           (__GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1300)
+    #elif _LIBCPP_VERSION
+        #define __TBB_EXCEPTION_PTR_PRESENT           __GXX_EXPERIMENTAL_CXX0X__
+    #else
+        #define __TBB_EXCEPTION_PTR_PRESENT           0
+    #endif
+    #define __TBB_STATIC_ASSERT_PRESENT               (__INTEL_CXX11_MODE__ || _MSC_VER >= 1600)
+    #define __TBB_CPP11_TUPLE_PRESENT                 (_MSC_VER >= 1600 || (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300))
+    /**Intel C++ compiler 14.0 crashes on using __has_include. When it fixed, condition will need to be updated. **/
+    #if (__clang__ && __INTEL_COMPILER > 1400)
+        #if (__has_feature(__cxx_generalized_initializers__) && __has_include(<initializer_list>))
+            #define __TBB_INITIALIZER_LISTS_PRESENT   1
+        #endif
+    #else
+        /** TODO: when MSVC2013 is supported by Intel C++ compiler, it will be enabled silently by compiler, so rule will need to be updated.**/
+        #define __TBB_INITIALIZER_LISTS_PRESENT       __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400 && (_MSC_VER >= 1800 || __TBB_GCC_VERSION >= 40400 || _LIBCPP_VERSION)
+    #endif
+    
+    #define __TBB_CONSTEXPR_PRESENT                   __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1400
+    #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT  __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1200
+    /** ICC seems to disable support of noexcept event in c++11 when compiling in compatibility mode for gcc <4.6 **/
+    #define __TBB_NOEXCEPT_PRESENT                    __INTEL_CXX11_MODE__ && __INTEL_COMPILER >= 1300 && (__TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION || _MSC_VER)
+    #define __TBB_CPP11_STD_BEGIN_END_PRESENT         (_MSC_VER >= 1700 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1310 && (__TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION))
+    #define __TBB_CPP11_AUTO_PRESENT                  (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210)
+    #define __TBB_CPP11_DECLTYPE_PRESENT              (_MSC_VER >= 1600 || __GXX_EXPERIMENTAL_CXX0X__ && __INTEL_COMPILER >= 1210)
+#elif __clang__
+//TODO: these options need to be rechecked
+/** on OS X* the only way to get C++11 is to use clang. For library features (e.g. exception_ptr) libc++ is also
+ *  required. So there is no need to check GCC version for clang**/
+    #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT     (__has_feature(__cxx_variadic_templates__))
+    #define __TBB_CPP11_RVALUE_REF_PRESENT             (__has_feature(__cxx_rvalue_references__) && (__TBB_GCC_VERSION >= 40300 || _LIBCPP_VERSION))
+/** TODO: extend exception_ptr related conditions to cover libstdc++ **/
+    #define __TBB_EXCEPTION_PTR_PRESENT               (__cplusplus >= 201103L && _LIBCPP_VERSION)
+    #define __TBB_STATIC_ASSERT_PRESENT               __has_feature(__cxx_static_assert__)
+    /**Clang (preprocessor) has problems with dealing with expression having __has_include in #ifs
+     * used inside C++ code. (At least version that comes with OS X 10.8 : Apple LLVM version 4.2 (clang-425.0.28) (based on LLVM 3.2svn)) **/
+    #if (__GXX_EXPERIMENTAL_CXX0X__ && __has_include(<tuple>))
+        #define __TBB_CPP11_TUPLE_PRESENT             1
+    #endif
+    #if (__has_feature(__cxx_generalized_initializers__) && __has_include(<initializer_list>))
+        #define __TBB_INITIALIZER_LISTS_PRESENT       1
+    #endif
+    #define __TBB_CONSTEXPR_PRESENT                   __has_feature(__cxx_constexpr__)
+    #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT  (__has_feature(__cxx_defaulted_functions__) && __has_feature(__cxx_deleted_functions__))
+    /**For some unknown reason  __has_feature(__cxx_noexcept) does not yield true for all cases. Compiler bug ? **/
+    #define __TBB_NOEXCEPT_PRESENT                    (__cplusplus >= 201103L)
+    #define __TBB_CPP11_STD_BEGIN_END_PRESENT         (__has_feature(__cxx_range_for__) && _LIBCPP_VERSION)
+    #define __TBB_CPP11_AUTO_PRESENT                  __has_feature(__cxx_auto_type__)
+    #define __TBB_CPP11_DECLTYPE_PRESENT              __has_feature(__cxx_decltype__)
+#elif __GNUC__
+    #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT    __GXX_EXPERIMENTAL_CXX0X__
+    #define __TBB_CPP11_RVALUE_REF_PRESENT            __GXX_EXPERIMENTAL_CXX0X__
+    /** __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 here is a substitution for _GLIBCXX_ATOMIC_BUILTINS_4, which is a prerequisite 
+        for exception_ptr but cannot be used in this file because it is defined in a header, not by the compiler. 
+        If the compiler has no atomic intrinsics, the C++ library should not expect those as well. **/
+    #define __TBB_EXCEPTION_PTR_PRESENT               (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40404 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    #define __TBB_STATIC_ASSERT_PRESENT               (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300)
+    #define __TBB_CPP11_TUPLE_PRESENT                 (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300)
+    #define __TBB_INITIALIZER_LISTS_PRESENT           (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400)
+    /** gcc seems have to support constexpr from 4.4 but tests in (test_atomic) seeming reasonable fail to compile prior 4.6**/
+    #define __TBB_CONSTEXPR_PRESENT                   (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400)
+    #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT  (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400)
+    #define __TBB_NOEXCEPT_PRESENT                    (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600)
+    #define __TBB_CPP11_STD_BEGIN_END_PRESENT         (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40600)
+    #define __TBB_CPP11_AUTO_PRESENT                  (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400)
+    #define __TBB_CPP11_DECLTYPE_PRESENT              (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40400)
+#elif _MSC_VER
+    #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT    (_MSC_VER >= 1800)
+    #define __TBB_CPP11_RVALUE_REF_PRESENT            (_MSC_VER >= 1600)
+    #define __TBB_EXCEPTION_PTR_PRESENT               (_MSC_VER >= 1600)
+    #define __TBB_STATIC_ASSERT_PRESENT               (_MSC_VER >= 1600)
+    #define __TBB_CPP11_TUPLE_PRESENT                 (_MSC_VER >= 1600)
+    #define __TBB_INITIALIZER_LISTS_PRESENT           (_MSC_VER >= 1800)
+    #define __TBB_CONSTEXPR_PRESENT                   0
+    #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT  (_MSC_VER >= 1800)
+    #define __TBB_NOEXCEPT_PRESENT                    0 /*for _MSC_VER == 1800*/
+    #define __TBB_CPP11_STD_BEGIN_END_PRESENT         (_MSC_VER >= 1700)
+    #define __TBB_CPP11_AUTO_PRESENT                  (_MSC_VER >= 1600)
+    #define __TBB_CPP11_DECLTYPE_PRESENT              (_MSC_VER >= 1600)
+#else
+    #define __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT    0
+    #define __TBB_CPP11_RVALUE_REF_PRESENT            0
+    #define __TBB_EXCEPTION_PTR_PRESENT               0
+    #define __TBB_STATIC_ASSERT_PRESENT               0
+    #define __TBB_CPP11_TUPLE_PRESENT                 0
+    #define __TBB_INITIALIZER_LISTS_PRESENT           0
+    #define __TBB_CONSTEXPR_PRESENT                   0
+    #define __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT  0
+    #define __TBB_NOEXCEPT_PRESENT                    0
+    #define __TBB_CPP11_STD_BEGIN_END_PRESENT         0
+    #define __TBB_CPP11_AUTO_PRESENT                  0
+    #define __TBB_CPP11_DECLTYPE_PRESENT              0
+#endif
+
+// C++11 standard library features
+
+#define __TBB_CPP11_TYPE_PROPERTIES_PRESENT         (_LIBCPP_VERSION || _MSC_VER >= 1700)
+#define __TBB_TR1_TYPE_PROPERTIES_IN_STD_PRESENT    (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40300 || _MSC_VER >= 1600)
+// GCC has a partial support of type properties
+#define __TBB_CPP11_IS_COPY_CONSTRUCTIBLE_PRESENT   (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 || __TBB_CPP11_TYPE_PROPERTIES_PRESENT)
+
+// In GCC and MSVC, implementation of std::move_if_noexcept is not aligned with noexcept
+#define __TBB_MOVE_IF_NOEXCEPT_PRESENT          (__GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 || _MSC_VER >= 1800 || __clang__ && _LIBCPP_VERSION && __TBB_NOEXCEPT_PRESENT)
+//TODO: Probably more accurate way is to analyze version of stdlibc++ via__GLIBCXX__ instead of __TBB_GCC_VERSION
+#define __TBB_ALLOCATOR_TRAITS_PRESENT              (__cplusplus >= 201103L && _LIBCPP_VERSION  || _MSC_VER >= 1700 ||                                             \
+                                                     __GXX_EXPERIMENTAL_CXX0X__ && __TBB_GCC_VERSION >= 40700 && !(__TBB_GCC_VERSION == 40700 && __TBB_DEFINE_MIC) \
+                                                    )
+#define __TBB_MAKE_EXCEPTION_PTR_PRESENT         (__TBB_EXCEPTION_PTR_PRESENT && (_MSC_VER >= 1700 || __TBB_GCC_VERSION >= 40600 || _LIBCPP_VERSION))
+
+//TODO: not clear how exactly this macro affects exception_ptr - investigate
+// On linux ICC fails to find existing std::exception_ptr in libstdc++ without this define
+#if __INTEL_COMPILER && __GNUC__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
+    #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+#endif
+
+// Work around a bug in MinGW32
+#if __MINGW32__ && __TBB_EXCEPTION_PTR_PRESENT && !defined(_GLIBCXX_ATOMIC_BUILTINS_4)
+    #define _GLIBCXX_ATOMIC_BUILTINS_4
+#endif
 
 #if __GNUC__ || __SUNPRO_CC || __IBMCPP__
     /* ICC defines __GNUC__ and so is covered */
     #define __TBB_DECLSPEC_ALIGN_PRESENT 1
 #endif
 
-#if (__TBB_GCC_VERSION >= 40102) && !defined(__INTEL_COMPILER)
+/* Actually ICC supports gcc __sync_* intrinsics starting 11.1,
+ * but 64 bit support for 32 bit target comes in later ones*/
+/* TODO: change the version back to 4.1.2 once macro __TBB_WORD_SIZE become optional */
+#if __TBB_GCC_VERSION >= 40306 || __INTEL_COMPILER >= 1200
     /** built-in atomics available in GCC since 4.1.2 **/
     #define __TBB_GCC_BUILTIN_ATOMICS_PRESENT 1
 #endif
 
+#if __INTEL_COMPILER >= 1200
+    /** built-in C++11 style atomics available in ICC since 12.0 **/
+    #define __TBB_ICC_BUILTIN_ATOMICS_PRESENT 1
+#endif
+
+#define __TBB_TSX_INTRINSICS_PRESENT ((__RTM__ || _MSC_VER>=1700 || __INTEL_COMPILER>=1300) && !__TBB_DEFINE_MIC && !__ANDROID__)
+
 /** User controlled TBB features & modes **/
 
 #ifndef TBB_USE_DEBUG
-#ifdef TBB_DO_ASSERT
-#define TBB_USE_DEBUG TBB_DO_ASSERT
-#else
 #ifdef _DEBUG
 #define TBB_USE_DEBUG _DEBUG
 #else
 #define TBB_USE_DEBUG 0
 #endif
-#endif /* TBB_DO_ASSERT */
 #endif /* TBB_USE_DEBUG */
 
 #ifndef TBB_USE_ASSERT
-#ifdef TBB_DO_ASSERT
-#define TBB_USE_ASSERT TBB_DO_ASSERT
-#else 
 #define TBB_USE_ASSERT TBB_USE_DEBUG
-#endif /* TBB_DO_ASSERT */
 #endif /* TBB_USE_ASSERT */
 
 #ifndef TBB_USE_THREADING_TOOLS
-#ifdef TBB_DO_THREADING_TOOLS
-#define TBB_USE_THREADING_TOOLS TBB_DO_THREADING_TOOLS
-#else 
 #define TBB_USE_THREADING_TOOLS TBB_USE_DEBUG
-#endif /* TBB_DO_THREADING_TOOLS */
 #endif /* TBB_USE_THREADING_TOOLS */
 
 #ifndef TBB_USE_PERFORMANCE_WARNINGS
 #ifdef TBB_PERFORMANCE_WARNINGS
 #define TBB_USE_PERFORMANCE_WARNINGS TBB_PERFORMANCE_WARNINGS
-#else 
+#else
 #define TBB_USE_PERFORMANCE_WARNINGS TBB_USE_DEBUG
 #endif /* TBB_PEFORMANCE_WARNINGS */
 #endif /* TBB_USE_PERFORMANCE_WARNINGS */
 
-
 #if !defined(__EXCEPTIONS) && !defined(_CPPUNWIND) && !defined(__SUNPRO_CC) || defined(_XBOX)
     #if TBB_USE_EXCEPTIONS
         #error Compilation settings do not support exception handling. Please do not set TBB_USE_EXCEPTIONS macro or set it to 0.
         #define TBB_USE_EXCEPTIONS 0
     #endif
 #elif !defined(TBB_USE_EXCEPTIONS)
+    #if __TBB_DEFINE_MIC
+    #define TBB_USE_EXCEPTIONS 0
+    #else
     #define TBB_USE_EXCEPTIONS 1
+    #endif
+#elif TBB_USE_EXCEPTIONS && __TBB_DEFINE_MIC
+    #error Please do not set TBB_USE_EXCEPTIONS macro or set it to 0.
 #endif
 
 #ifndef TBB_IMPLEMENT_CPP0X
-    /** By default, use C++0x classes if available **/
+    /** By default, use C++11 classes if available **/
     #if __GNUC__==4 && __GNUC_MINOR__>=4 && __GXX_EXPERIMENTAL_CXX0X__
         #define TBB_IMPLEMENT_CPP0X 0
+    #elif __clang__ && __cplusplus >= 201103L
+        //TODO: consider introducing separate macros for each file?
+        //prevent injection of corresponding tbb names into std:: namespace if native headers are present
+        #if __has_include(<thread>) || __has_include(<condition_variable>)
+            #define TBB_IMPLEMENT_CPP0X 0
+        #else
+            #define TBB_IMPLEMENT_CPP0X 1
+        #endif
+    #elif _MSC_VER>=1700
+        #define TBB_IMPLEMENT_CPP0X 0
+    #elif __STDCPP_THREADS__
+        #define TBB_IMPLEMENT_CPP0X 0
     #else
         #define TBB_IMPLEMENT_CPP0X 1
     #endif
 #endif /* TBB_IMPLEMENT_CPP0X */
 
+/* TBB_USE_CAPTURED_EXCEPTION should be explicitly set to either 0 or 1, as it is used as C++ const */
 #ifndef TBB_USE_CAPTURED_EXCEPTION
-    #if __TBB_EXCEPTION_PTR_PRESENT
+    /** IA-64 architecture pre-built TBB binaries do not support exception_ptr. **/
+    #if __TBB_EXCEPTION_PTR_PRESENT && !defined(__ia64__)
         #define TBB_USE_CAPTURED_EXCEPTION 0
     #else
         #define TBB_USE_CAPTURED_EXCEPTION 1
 #endif /* defined TBB_USE_CAPTURED_EXCEPTION */
 
 /** Check whether the request to use GCC atomics can be satisfied **/
-#if (TBB_USE_GCC_BUILTINS && !__TBB_GCC_BUILTIN_ATOMICS_PRESENT)
+#if TBB_USE_GCC_BUILTINS && !__TBB_GCC_BUILTIN_ATOMICS_PRESENT
     #error "GCC atomic built-ins are not supported."
 #endif
 
 /** Internal TBB features & modes **/
 
+/** __TBB_WEAK_SYMBOLS_PRESENT denotes that the system supports the weak symbol mechanism **/
+#ifndef __TBB_WEAK_SYMBOLS_PRESENT
+#define __TBB_WEAK_SYMBOLS_PRESENT ( !_WIN32 && !__APPLE__ && !__sun && (__TBB_GCC_VERSION >= 40000 || __INTEL_COMPILER ) )
+#endif
+
+/** __TBB_DYNAMIC_LOAD_ENABLED describes the system possibility to load shared libraries at run time **/
 #ifndef __TBB_DYNAMIC_LOAD_ENABLED
-    #define __TBB_DYNAMIC_LOAD_ENABLED !__TBB_TASK_CPP_DIRECTLY_INCLUDED
-#elif !__TBB_DYNAMIC_LOAD_ENABLED
-    #if _WIN32||_WIN64
-        #define __TBB_NO_IMPLICIT_LINKAGE 1
-        #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1
-    #else
-        #define __TBB_WEAK_SYMBOLS 1
-    #endif
+    #define __TBB_DYNAMIC_LOAD_ENABLED 1
+#endif
+
+/** __TBB_SOURCE_DIRECTLY_INCLUDED is a mode used in whitebox testing when
+    it's necessary to test internal functions not exported from TBB DLLs
+**/
+#if (_WIN32||_WIN64) && (__TBB_SOURCE_DIRECTLY_INCLUDED || TBB_USE_PREVIEW_BINARY)
+    #define __TBB_NO_IMPLICIT_LINKAGE 1
+    #define __TBBMALLOC_NO_IMPLICIT_LINKAGE 1
 #endif
 
 #ifndef __TBB_COUNT_TASK_NODES
     #define __TBB_TASK_GROUP_CONTEXT 1
 #endif /* __TBB_TASK_GROUP_CONTEXT */
 
-#if TBB_USE_EXCEPTIONS && !__TBB_TASK_GROUP_CONTEXT
-    #error TBB_USE_EXCEPTIONS requires __TBB_TASK_GROUP_CONTEXT to be enabled
-#endif
-
 #ifndef __TBB_SCHEDULER_OBSERVER
     #define __TBB_SCHEDULER_OBSERVER 1
 #endif /* __TBB_SCHEDULER_OBSERVER */
 
+#ifndef __TBB_FP_CONTEXT
+    #define __TBB_FP_CONTEXT __TBB_TASK_GROUP_CONTEXT
+#endif /* __TBB_FP_CONTEXT */
+
+#if __TBB_FP_CONTEXT && !__TBB_TASK_GROUP_CONTEXT
+    #error __TBB_FP_CONTEXT requires __TBB_TASK_GROUP_CONTEXT to be enabled
+#endif
+
+#ifndef __TBB_TASK_ARENA
+    #define __TBB_TASK_ARENA 1
+#endif /* __TBB_TASK_ARENA  */
+#if __TBB_TASK_ARENA
+    #define __TBB_RECYCLE_TO_ENQUEUE __TBB_BUILD // keep non-official
+    #if !__TBB_SCHEDULER_OBSERVER
+        #error __TBB_TASK_ARENA requires __TBB_SCHEDULER_OBSERVER to be enabled
+    #endif
+#endif /* __TBB_TASK_ARENA */
+
+#ifndef __TBB_ARENA_OBSERVER
+    #define __TBB_ARENA_OBSERVER ((__TBB_BUILD||TBB_PREVIEW_LOCAL_OBSERVER)&& __TBB_SCHEDULER_OBSERVER)
+#endif /* __TBB_ARENA_OBSERVER */
+
+#ifndef __TBB_SLEEP_PERMISSION
+    #define __TBB_SLEEP_PERMISSION ((__TBB_CPF_BUILD||TBB_PREVIEW_LOCAL_OBSERVER)&& __TBB_SCHEDULER_OBSERVER)
+#endif /* __TBB_SLEEP_PERMISSION */
+
+#if TBB_PREVIEW_FLOW_GRAPH_TRACE
+#define __TBB_NO_IMPLICIT_LINKAGE 1
+#endif /* TBB_PREVIEW_FLOW_GRAPH_TRACE */
+
+#ifndef __TBB_ITT_STRUCTURE_API
+#define __TBB_ITT_STRUCTURE_API ( !__TBB_DEFINE_MIC && (__TBB_CPF_BUILD || TBB_PREVIEW_FLOW_GRAPH_TRACE) )
+#endif
+
+#if TBB_USE_EXCEPTIONS && !__TBB_TASK_GROUP_CONTEXT
+    #error TBB_USE_EXCEPTIONS requires __TBB_TASK_GROUP_CONTEXT to be enabled
+#endif
+
 #ifndef __TBB_TASK_PRIORITY
-    #define __TBB_TASK_PRIORITY __TBB_TASK_GROUP_CONTEXT
+    #define __TBB_TASK_PRIORITY (__TBB_TASK_GROUP_CONTEXT)
 #endif /* __TBB_TASK_PRIORITY */
 
 #if __TBB_TASK_PRIORITY && !__TBB_TASK_GROUP_CONTEXT
     #error __TBB_TASK_PRIORITY requires __TBB_TASK_GROUP_CONTEXT to be enabled
 #endif
 
-#if !defined(__TBB_SURVIVE_THREAD_SWITCH) && (_WIN32 || _WIN64 || __linux__)
+#if TBB_PREVIEW_WAITING_FOR_WORKERS || __TBB_BUILD
+    #define __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE 1
+#endif
+
+#if !defined(__TBB_SURVIVE_THREAD_SWITCH) && \
+          (_WIN32 || _WIN64 || __APPLE__ || (__linux__ && !__ANDROID__))
     #define __TBB_SURVIVE_THREAD_SWITCH 1
 #endif /* __TBB_SURVIVE_THREAD_SWITCH */
 
 #endif /* TBB_DEPRECATED */
 #endif /* !defined(__TBB_DEFAULT_PARTITIONER */
 
+#ifndef __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES
+#define __TBB_USE_PROPORTIONAL_SPLIT_IN_BLOCKED_RANGES 1
+#endif
+
+#ifndef __TBB_ENABLE_RANGE_FEEDBACK
+#define __TBB_ENABLE_RANGE_FEEDBACK 0
+#endif
+
+#ifdef _VARIADIC_MAX
+#define __TBB_VARIADIC_MAX _VARIADIC_MAX
+#else
+#if _MSC_VER >= 1700
+#define __TBB_VARIADIC_MAX 5  /* current VS11 setting, may change. */
+#else
+#define __TBB_VARIADIC_MAX 10
+#endif
+#endif
+
+/** __TBB_WIN8UI_SUPPORT enables support of New Windows*8 Store Apps and limit a possibility to load
+    shared libraries at run time only from application container **/
+#if defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP
+    #define __TBB_WIN8UI_SUPPORT 1
+#else
+    #define __TBB_WIN8UI_SUPPORT 0
+#endif
+
 /** Macros of the form __TBB_XXX_BROKEN denote known issues that are caused by
-    the bugs in compilers, standard or OS specific libraries. They should be 
+    the bugs in compilers, standard or OS specific libraries. They should be
     removed as soon as the corresponding bugs are fixed or the buggy OS/compiler
-    versions go out of the support list. 
+    versions go out of the support list.
 **/
 
+#if __ANDROID__ && __TBB_GCC_VERSION <= 40403 && !__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8
+    /** Necessary because on Android 8-byte CAS and F&A are not available for some processor architectures,
+        but no mandatory warning message appears from GCC 4.4.3. Instead, only a linkage error occurs when
+        these atomic operations are used (such as in unit test test_atomic.exe). **/
+    #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1
+#elif __TBB_x86_32 && __TBB_GCC_VERSION == 40102 && ! __GNUC_RH_RELEASE__
+    /** GCC 4.1.2 erroneously emit call to external function for 64 bit sync_ intrinsics.
+        However these functions are not defined anywhere. It seems that this problem was fixed later on
+        and RHEL got an updated version of gcc 4.1.2. **/
+    #define __TBB_GCC_64BIT_ATOMIC_BUILTINS_BROKEN 1
+#endif
+
 #if __GNUC__ && __TBB_x86_64 && __INTEL_COMPILER == 1200
     #define __TBB_ICC_12_0_INL_ASM_FSTCW_BROKEN 1
 #endif
 
 #if _MSC_VER && __INTEL_COMPILER && (__INTEL_COMPILER<1110 || __INTEL_COMPILER==1110 && __INTEL_COMPILER_BUILD_DATE < 20091012)
-    /** Necessary to avoid ICL error (or warning in non-strict mode): 
-        "exception specification for implicitly declared virtual destructor is 
+    /** Necessary to avoid ICL error (or warning in non-strict mode):
+        "exception specification for implicitly declared virtual destructor is
         incompatible with that of overridden one". **/
     #define __TBB_DEFAULT_DTOR_THROW_SPEC_BROKEN 1
 #endif
 
-#if defined(_MSC_VER) && _MSC_VER < 1500 && !defined(__INTEL_COMPILER)
-    /** VS2005 and earlier do not allow declaring template class as a friend 
+#if !__INTEL_COMPILER && (_MSC_VER && _MSC_VER < 1500 || __TBB_GCC_VERSION && __TBB_GCC_VERSION < 40102)
+    /** gcc 3.4.6 (and earlier) and VS2005 (and earlier) do not allow declaring template class as a friend
         of classes defined in other namespaces. **/
     #define __TBB_TEMPLATE_FRIENDS_BROKEN 1
 #endif
 
-#if __GLIBC__==2 && __GLIBC_MINOR__==3 || __MINGW32__ || (__APPLE__ && __INTEL_COMPILER==1200 && !TBB_USE_DEBUG)
-    //! Macro controlling EH usages in TBB tests
-    /** Some older versions of glibc crash when exception handling happens concurrently. **/
+//TODO: recheck for different clang versions 
+#if __GLIBC__==2 && __GLIBC_MINOR__==3 ||  (__APPLE__ && ( __INTEL_COMPILER==1200 && !TBB_USE_DEBUG))
+    /** Macro controlling EH usages in TBB tests.
+        Some older versions of glibc crash when exception handling happens concurrently. **/
     #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 1
+#else
+    #define __TBB_THROW_ACROSS_MODULE_BOUNDARY_BROKEN 0
 #endif
 
 #if (_WIN32||_WIN64) && __INTEL_COMPILER == 1110
     #define __TBB_ICL_11_1_CODE_GEN_BROKEN 1
 #endif
 
-#if __GNUC__==3 && __GNUC_MINOR__==3 && !defined(__INTEL_COMPILER)
-    /** A bug in GCC 3.3 with access to nested classes declared in protected area */
-    #define __TBB_GCC_3_3_PROTECTED_BROKEN 1
+#if __clang__ || (__GNUC__==3 && __GNUC_MINOR__==3 && !defined(__INTEL_COMPILER))
+    /** Bugs with access to nested classes declared in protected area */
+    #define __TBB_PROTECTED_NESTED_CLASS_BROKEN 1
 #endif
 
-#if __MINGW32__ && (__GNUC__<4 || __GNUC__==4 && __GNUC_MINOR__<2)
+#if __MINGW32__ && __TBB_GCC_VERSION < 40200
     /** MinGW has a bug with stack alignment for routines invoked from MS RTLs.
         Since GCC 4.2, the bug can be worked around via a special attribute. **/
     #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 1
+#else
+    #define __TBB_SSE_STACK_ALIGNMENT_BROKEN 0
 #endif
 
 #if __GNUC__==4 && __GNUC_MINOR__==3 && __GNUC_PATCHLEVEL__==0
-    // GCC of this version may rashly ignore control dependencies
+    /* GCC of this version may rashly ignore control dependencies */
     #define __TBB_GCC_OPTIMIZER_ORDERING_BROKEN 1
 #endif
 
 #if __FreeBSD__
-    /** A bug in FreeBSD 8.0 results in kernel panic when there is contention 
+    /** A bug in FreeBSD 8.0 results in kernel panic when there is contention
         on a mutex created with this attribute. **/
     #define __TBB_PRIO_INHERIT_BROKEN 1
 
-    /** A bug in FreeBSD 8.0 results in test hanging when an exception occurs 
+    /** A bug in FreeBSD 8.0 results in test hanging when an exception occurs
         during (concurrent?) object construction by means of placement new operator. **/
     #define __TBB_PLACEMENT_NEW_EXCEPTION_SAFETY_BROKEN 1
 #endif /* __FreeBSD__ */
 
 #if (__linux__ || __APPLE__) && __i386__ && defined(__INTEL_COMPILER)
-    /** The Intel compiler for IA-32 (Linux|Mac OS X) crashes or generates 
+    /** The Intel compiler for IA-32 (Linux|OS X) crashes or generates
         incorrect code when __asm__ arguments have a cast to volatile. **/
     #define __TBB_ICC_ASM_VOLATILE_BROKEN 1
 #endif
 
 #if !__INTEL_COMPILER && (_MSC_VER || __GNUC__==3 && __GNUC_MINOR__<=2)
-    /** Bug in GCC 3.2 and MSVC compilers that sometimes return 0 for __alignof(T) 
+    /** Bug in GCC 3.2 and MSVC compilers that sometimes return 0 for __alignof(T)
         when T has not yet been instantiated. **/
     #define __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN 1
 #endif
 
+#if __TBB_DEFINE_MIC
+    /** Main thread and user's thread have different default thread affinity masks. **/
+    #define __TBB_MAIN_THREAD_AFFINITY_BROKEN 1
+#endif
+
+#if __GXX_EXPERIMENTAL_CXX0X__ && !defined(__EXCEPTIONS) && \
+    ((!__INTEL_COMPILER && !__clang__ && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<40600)) || \
+     (__INTEL_COMPILER<=1400 && (__TBB_GCC_VERSION>=40400 && __TBB_GCC_VERSION<=40801)))
+/* There is an issue for specific GCC toolchain when C++11 is enabled
+   and exceptions are disabled:
+   exceprion_ptr.h/nested_exception.h use throw unconditionally.
+   GCC can ignore 'throw' since 4.6; but with ICC the issue still exists.
+ */
+    #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 1
+#else
+    #define __TBB_LIBSTDCPP_EXCEPTION_HEADERS_BROKEN 0
+#endif
+
+#if __INTEL_COMPILER==1300 && __TBB_GCC_VERSION>=40700 && defined(__GXX_EXPERIMENTAL_CXX0X__)
+/* Some C++11 features used inside libstdc++ are not supported by Intel compiler.
+ * Checking version of gcc instead of libstdc++ because
+ *  - they are directly connected,
+ *  - for now it is not possible to check version of any standard library in this file
+ */
+    #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 1
+#else
+    #define __TBB_ICC_13_0_CPP11_STDLIB_SUPPORT_BROKEN 0
+#endif
+
+#if (__GNUC__==4 && __GNUC_MINOR__==4 ) && !defined(__INTEL_COMPILER) && !defined(__clang__)
+    /** excessive warnings related to strict aliasing rules in GCC 4.4 **/
+    #define __TBB_GCC_STRICT_ALIASING_BROKEN 1
+    /* topical remedy: #pragma GCC diagnostic ignored "-Wstrict-aliasing" */
+    #if !__TBB_GCC_WARNING_SUPPRESSION_PRESENT
+        #error Warning suppression is not supported, while should.
+    #endif
+#endif
+
+/*In a PIC mode some versions of GCC 4.1.2 generate incorrect inlined code for 8 byte __sync_val_compare_and_swap intrinsic */
+#if __TBB_GCC_VERSION == 40102 && __PIC__ && !defined(__INTEL_COMPILER) && !defined(__clang__)
+    #define __TBB_GCC_CAS8_BUILTIN_INLINING_BROKEN 1
+#endif
+
+#if __TBB_x86_32 && (__linux__ || __APPLE__ || _WIN32 || __sun || __ANDROID__) &&  (__INTEL_COMPILER || (__GNUC__==3 && __GNUC_MINOR__==3 ) || __SUNPRO_CC)
+    // Some compilers for IA-32 fail to provide 8-byte alignment of objects on the stack,
+    // even if the object specifies 8-byte alignment.  On such platforms, the IA-32 implementation
+    // of 64 bit atomics (e.g. atomic<long long>) use different tactics depending upon
+    // whether the object is properly aligned or not.
+    #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 1
+#else
+    #define __TBB_FORCE_64BIT_ALIGNMENT_BROKEN 0
+#endif
+
+#if __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && __TBB_GCC_VERSION < 40700 && !defined(__INTEL_COMPILER) && !defined (__clang__)
+    #define __TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN 1
+#endif
+
+#if _MSC_VER && _MSC_VER <= 1800 && !__INTEL_COMPILER
+    // With MSVC, when an array is passed by const reference to a template function,
+    // constness from the function parameter may get propagated to the template parameter.
+    #define __TBB_CONST_REF_TO_ARRAY_TEMPLATE_PARAM_BROKEN 1
+#endif
+
+// A compiler bug: a disabled copy constructor prevents use of the moving constructor
+#define __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN (_MSC_VER && (__INTEL_COMPILER >= 1300 && __INTEL_COMPILER <= 1310) && !__INTEL_CXX11_MODE__)
+
+// MSVC 2013 and ICC 15 seems do not generate implicit move constructor for empty derived class while should
+#define __TBB_CPP11_IMPLICIT_MOVE_MEMBERS_GENERATION_FOR_DERIVED_BROKEN  (__TBB_CPP11_RVALUE_REF_PRESENT &&  \
+      ( !__INTEL_COMPILER && _MSC_VER && _MSC_VER <=1800 || __INTEL_COMPILER && __INTEL_COMPILER <= 1500 ))
+
+/** End of __TBB_XXX_BROKEN macro section **/
+
+#if defined(_MSC_VER) && _MSC_VER>=1500 && !defined(__INTEL_COMPILER)
+    // A macro to suppress erroneous or benign "unreachable code" MSVC warning (4702)
+    #define __TBB_MSVC_UNREACHABLE_CODE_IGNORED 1
+#endif
+
+#define __TBB_ATOMIC_CTORS     (__TBB_CONSTEXPR_PRESENT && __TBB_DEFAULTED_AND_DELETED_FUNC_PRESENT && (!__TBB_ZERO_INIT_WITH_DEFAULTED_CTOR_BROKEN))
+
+#define __TBB_ALLOCATOR_CONSTRUCT_VARIADIC      (__TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT)
+
+#define __TBB_VARIADIC_PARALLEL_INVOKE          (TBB_PREVIEW_VARIADIC_PARALLEL_INVOKE && __TBB_CPP11_VARIADIC_TEMPLATES_PRESENT && __TBB_CPP11_RVALUE_REF_PRESENT)
 #endif /* __TBB_tbb_config_H */
index 23466909c09480b23f8442448d4e3e2335678d85..cfef55ef389d7e841cedff093224663f0897356f 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_exception_H
@@ -37,7 +29,8 @@
     #pragma warning (disable: 4530)
 #endif
 
-#include <stdexcept>
+#include <exception>
+#include <new>    //required for bad_alloc definition, operators new
 #include <string> // required to construct std exception classes
 
 #if !TBB_USE_EXCEPTIONS && _MSC_VER
@@ -61,6 +54,12 @@ public:
     /*override*/ const char* what() const throw();
 };
 
+//! Exception for user-initiated abort
+class user_abort : public std::exception {
+public:
+    /*override*/ const char* what() const throw();
+};
+
 //! Exception for missing wait on structured_task_group
 class missing_wait : public std::exception {
 public:
@@ -95,6 +94,14 @@ enum exception_id {
     eid_invalid_swap,
     eid_reservation_length_error,
     eid_invalid_key,
+    eid_user_abort,
+    eid_reserved1,
+#if __TBB_SUPPORTS_WORKERS_WAITING_IN_TERMINATE
+    // This id is used only inside library and only for support of CPF functionality.
+    // So, if we drop the functionality, eid_reserved1 can be safely renamed and reused.
+    eid_blocking_sch_init = eid_reserved1,
+#endif
+    eid_bad_tagged_msg_cast,
     //! The last enumerator tracks the number of defined IDs. It must remain the last one.
     /** When adding new IDs, place them immediately _before_ this comment (that is
         _after_ all the existing IDs. NEVER insert new IDs between the existing ones. **/
@@ -114,9 +121,7 @@ inline void throw_exception ( exception_id eid ) { throw_exception_v4(eid); }
 
 #if __TBB_TASK_GROUP_CONTEXT
 #include "tbb_allocator.h"
-#include <exception>
-#include <typeinfo>
-#include <new>
+#include <typeinfo> //for typeid
 
 namespace tbb {
 
@@ -149,6 +154,14 @@ class tbb_exception : public std::exception
     void* operator new ( size_t );
 
 public:
+#if __clang__
+    // At -O3 or even -O2 optimization level, Clang may fully throw away an empty destructor
+    // of tbb_exception from destructors of derived classes. As a result, it does not create
+    // vtable for tbb_exception, which is a required part of TBB binary interface.
+    // Making the destructor non-empty (with just a semicolon) prevents that optimization.
+    ~tbb_exception() throw() { /* keep the semicolon! */ ; }
+#endif
+
     //! Creates and returns pointer to the deep copy of this exception object.
     /** Move semantics is allowed. **/
     virtual tbb_exception* move () throw() = 0;
@@ -347,7 +360,13 @@ public:
 
 private:
     tbb_exception_ptr ( const std::exception_ptr& src ) : my_ptr(src) {}
-    tbb_exception_ptr ( const captured_exception& src ) : my_ptr(std::copy_exception(src)) {}
+    tbb_exception_ptr ( const captured_exception& src ) :
+        #if __TBB_MAKE_EXCEPTION_PTR_PRESENT
+            my_ptr(std::make_exception_ptr(src))  // the final function name in C++11
+        #else
+            my_ptr(std::copy_exception(src))      // early C++0x drafts name
+        #endif
+    {}
 }; // class tbb::internal::tbb_exception_ptr
 
 } // namespace internal
index 50636e5d274e8d4d8bd186fdba587d32a8ef8f4b..4798065296dd142ce5c87de69a37f55bc5ee7005 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_machine_H
@@ -48,7 +40,7 @@
 
     In this case tbb_machine.h will add missing functionality based on a minimal set 
     of APIs that are required to be implemented by all plug-n headers as described
-    futher.
+    further.
     Note that these generic implementations may be sub-optimal for a particular
     architecture, and thus should be relied upon only after careful evaluation
     or as the last resort.
     be set to 1 explicitly, though normally this is not necessary as tbb_machine.h
     will set it automatically.
 
+    __TBB_ENDIANNESS macro can be defined by the implementation as well.
+    It is used only if __TBB_USE_GENERIC_PART_WORD_CAS is set (or for testing),
+    and must specify the layout of aligned 16-bit and 32-bit data anywhere within a process
+    (while the details of unaligned 16-bit or 32-bit data or of 64-bit data are irrelevant).
+    The layout must be the same at all relevant memory locations within the current process;
+    in case of page-specific endianness, one endianness must be kept "out of sight".
+    Possible settings, reflecting hardware and possibly O.S. convention, are:
+    -  __TBB_ENDIAN_BIG for big-endian data,
+    -  __TBB_ENDIAN_LITTLE for little-endian data,
+    -  __TBB_ENDIAN_DETECT for run-time detection iff exactly one of the above,
+    -  __TBB_ENDIAN_UNSUPPORTED to prevent undefined behavior if none of the above.
+
     Prerequisites for each architecture port
     ----------------------------------------
-    The following functions have no generic implementation. Therefore they must be 
+    The following functions and macros have no generic implementation. Therefore they must be
     implemented in each machine architecture specific header either as a conventional
     function or as a functional macro.
 
+    __TBB_WORDSIZE
+        This is the size of machine word in bytes, i.e. for 32 bit systems it
+        should be defined to 4.
+
     __TBB_Yield()
         Signals OS that the current thread is willing to relinquish the remainder
         of its time quantum.
     __TBB_control_consistency_helper()
         Bridges the memory-semantics gap between architectures providing only
         implicit C++0x "consume" semantics (like Power Architecture) and those
-        also implicitly obeying control dependencies (like Itanium).
+        also implicitly obeying control dependencies (like IA-64 architecture).
         It must be used only in conditional code where the condition is itself
         data-dependent, and will then make subsequent code behave as if the
         original data dependency were acquired.
-        It needs only an empty definition where implied by the architecture
-        either specifically (Itanium) or because generally stronger C++0x "acquire"
-        semantics are enforced (like x86).
-    
+        It needs only a compiler fence where implied by the architecture
+        either specifically (like IA-64 architecture) or because generally stronger 
+        "acquire" semantics are enforced (like x86).
+        It is always valid, though potentially suboptimal, to replace
+        control with acquire on the load and then remove the helper.
+
     __TBB_acquire_consistency_helper(), __TBB_release_consistency_helper()
         Must be provided if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE is set.
         Enforce acquire and release semantics in generic implementations of fenced
 #include "tbb_stddef.h"
 
 namespace tbb {
-namespace internal {
+namespace internal { //< @cond INTERNAL
 
 ////////////////////////////////////////////////////////////////////////////////
 // Overridable helpers declarations
@@ -154,7 +164,29 @@ template<> struct atomic_selector<8> {
     inline static word fetch_store ( volatile void* location, word value );
 };
 
-}} // namespaces internal, tbb
+}} //< namespaces internal @endcond, tbb
+
+#define __TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(M)                                        \
+    inline void __TBB_machine_generic_store8##M(volatile void *ptr, int64_t value) {         \
+        for(;;) {                                                                            \
+            int64_t result = *(volatile int64_t *)ptr;                                       \
+            if( __TBB_machine_cmpswp8##M(ptr,value,result)==result ) break;                  \
+        }                                                                                    \
+    }                                                                                        \
+
+#define __TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(M)                                         \
+    inline int64_t __TBB_machine_generic_load8##M(const volatile void *ptr) {                \
+        /* Comparand and new value may be anything, they only must be equal, and      */     \
+        /* the value should have a low probability to be actually found in 'location'.*/     \
+        const int64_t anyvalue = 2305843009213693951LL;                                      \
+        return __TBB_machine_cmpswp8##M(const_cast<volatile void *>(ptr),anyvalue,anyvalue); \
+    }                                                                                        \
+
+// The set of allowed values for __TBB_ENDIANNESS (see above for details)
+#define __TBB_ENDIAN_UNSUPPORTED -1
+#define __TBB_ENDIAN_LITTLE       0
+#define __TBB_ENDIAN_BIG          1
+#define __TBB_ENDIAN_DETECT       2
 
 #if _WIN32||_WIN64
 
@@ -172,22 +204,37 @@ template<> struct atomic_selector<8> {
         #elif __MINGW32__
             #include "machine/linux_ia32.h"
         #endif
-    #elif defined(_M_IX86)
+    #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT)
+        #include "machine/icc_generic.h"
+    #elif defined(_M_IX86) && !defined(__TBB_WIN32_USE_CL_BUILTINS)
         #include "machine/windows_ia32.h"
     #elif defined(_M_X64) 
         #include "machine/windows_intel64.h"
-    #elif _XBOX
+    #elif defined(_XBOX)
         #include "machine/xbox360_ppc.h"
+    #elif defined(_M_ARM) || defined(__TBB_WIN32_USE_CL_BUILTINS)
+        #include "machine/msvc_armv7.h"
     #endif
 
 #ifdef _MANAGED
 #pragma managed(pop)
 #endif
 
+#elif __TBB_DEFINE_MIC
+
+    #include "machine/mic_common.h"
+    #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT)
+        #include "machine/icc_generic.h"
+    #else
+        #include "machine/linux_intel64.h"
+    #endif
+
 #elif __linux__ || __FreeBSD__ || __NetBSD__
 
     #if (TBB_USE_GCC_BUILTINS && __TBB_GCC_BUILTIN_ATOMICS_PRESENT)
         #include "machine/gcc_generic.h"
+    #elif (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT)
+        #include "machine/icc_generic.h"
     #elif __i386__
         #include "machine/linux_ia32.h"
     #elif __x86_64__
@@ -196,14 +243,18 @@ template<> struct atomic_selector<8> {
         #include "machine/linux_ia64.h"
     #elif __powerpc__
         #include "machine/mac_ppc.h"
+    #elif __arm__
+        #include "machine/gcc_armv7.h"
     #elif __TBB_GCC_BUILTIN_ATOMICS_PRESENT
         #include "machine/gcc_generic.h"
     #endif
     #include "machine/linux_common.h"
 
 #elif __APPLE__
-
-    #if __i386__
+    //TODO:  TBB_USE_GCC_BUILTINS is not used for Mac, Sun, Aix
+    #if (TBB_USE_ICC_BUILTINS && __TBB_ICC_BUILTIN_ATOMICS_PRESENT)
+        #include "machine/icc_generic.h"
+    #elif __i386__
         #include "machine/linux_ia32.h"
     #elif __x86_64__
         #include "machine/linux_intel64.h"
@@ -238,6 +289,8 @@ template<> struct atomic_selector<8> {
     #define __TBB_64BIT_ATOMICS 1
 #endif
 
+//TODO: replace usage of these functions with usage of tbb::atomic, and then remove them
+//TODO: map functions with W suffix to use cast to tbb::atomic and according op, i.e. as_atomic().op()
 // Special atomic functions
 #if __TBB_USE_FENCED_ATOMICS
     #define __TBB_machine_cmpswp1   __TBB_machine_cmpswp1full_fence
@@ -252,7 +305,11 @@ template<> struct atomic_selector<8> {
         #define __TBB_FetchAndIncrementWacquire(P)  __TBB_machine_fetchadd8acquire(P,1)
         #define __TBB_FetchAndDecrementWrelease(P)  __TBB_machine_fetchadd8release(P,(-1))
     #else
-        #error Define macros for 4-byte word, similarly to the above __TBB_WORDSIZE==8 branch.
+        #define __TBB_machine_fetchadd4             __TBB_machine_fetchadd4full_fence
+        #define __TBB_machine_fetchstore4           __TBB_machine_fetchstore4full_fence
+        #define __TBB_FetchAndAddWrelease(P,V)      __TBB_machine_fetchadd4release(P,V)
+        #define __TBB_FetchAndIncrementWacquire(P)  __TBB_machine_fetchadd4acquire(P,1)
+        #define __TBB_FetchAndDecrementWrelease(P)  __TBB_machine_fetchadd4release(P,(-1))
     #endif /* __TBB_WORDSIZE==4 */
 #else /* !__TBB_USE_FENCED_ATOMICS */
     #define __TBB_FetchAndAddWrelease(P,V)      __TBB_FetchAndAddW(P,V)
@@ -287,7 +344,7 @@ namespace tbb {
 //! Sequentially consistent full memory fence.
 inline void atomic_fence () { __TBB_full_memory_fence(); }
 
-namespace internal {
+namespace internal { //< @cond INTERNAL
 
 //! Class that implements exponential backoff.
 /** See implementation of spin_wait_while_eq for an example. */
@@ -298,7 +355,12 @@ class atomic_backoff : no_copy {
     static const int32_t LOOPS_BEFORE_YIELD = 16;
     int32_t count;
 public:
+    // In many cases, an object of this type is initialized eagerly on hot path,
+    // as in for(atomic_backoff b; ; b.pause()) { /*loop body*/ }
+    // For this reason, the construction cost must be very small!
     atomic_backoff() : count(1) {}
+    // This constructor pauses immediately; do not use on hot paths!
+    atomic_backoff( bool ) : count(1) { pause(); }
 
     //! Pause for a while.
     void pause() {
@@ -345,127 +407,161 @@ void spin_wait_until_eq( const volatile T& location, const U value ) {
     while( location!=value ) backoff.pause();
 }
 
-// T should be unsigned, otherwise sign propagation will break correctness of bit manipulations.
-// S should be either 1 or 2, for the mask calculation to work correctly.
-// Together, these rules limit applicability of Masked CAS to unsigned char and unsigned short.
-template<size_t S, typename T>
-inline T __TBB_MaskedCompareAndSwap (volatile T *ptr, T value, T comparand ) {
-    volatile uint32_t * base = (uint32_t*)( (uintptr_t)ptr & ~(uintptr_t)0x3 );
-#if __TBB_BIG_ENDIAN
-    const uint8_t bitoffset = uint8_t( 8*( 4-S - (uintptr_t(ptr) & 0x3) ) );
-#else
-    const uint8_t bitoffset = uint8_t( 8*((uintptr_t)ptr & 0x3) );
+template <typename predicate_type>
+void spin_wait_while(predicate_type condition){
+    atomic_backoff backoff;
+    while( condition() ) backoff.pause();
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// Generic compare-and-swap applied to only a part of a machine word.
+//
+#ifndef __TBB_ENDIANNESS
+#define __TBB_ENDIANNESS __TBB_ENDIAN_DETECT
 #endif
-    const uint32_t mask = ( (1<<(S*8)) - 1 )<<bitoffset;
-    atomic_backoff b;
-    uint32_t result;
-    for(;;) {
-        result = *base; // reload the base value which might change during the pause
-        uint32_t old_value = ( result & ~mask ) | ( comparand << bitoffset );
-        uint32_t new_value = ( result & ~mask ) | ( value << bitoffset );
-        // __TBB_CompareAndSwap4 presumed to have full fence.
+
+#if __TBB_USE_GENERIC_PART_WORD_CAS && __TBB_ENDIANNESS==__TBB_ENDIAN_UNSUPPORTED
+#error Generic implementation of part-word CAS may not be used with __TBB_ENDIAN_UNSUPPORTED
+#endif
+
+#if __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED
+//
+// This function is the only use of __TBB_ENDIANNESS.
+// The following restrictions/limitations apply for this operation:
+//  - T must be an integer type of at most 4 bytes for the casts and calculations to work
+//  - T must also be less than 4 bytes to avoid compiler warnings when computing mask
+//      (and for the operation to be useful at all, so no workaround is applied)
+//  - the architecture must consistently use either little-endian or big-endian (same for all locations)
+//
+// TODO: static_assert for the type requirements stated above
+template<typename T>
+inline T __TBB_MaskedCompareAndSwap (volatile T * const ptr, const T value, const T comparand ) {
+    struct endianness{ static bool is_big_endian(){
+        #if __TBB_ENDIANNESS==__TBB_ENDIAN_DETECT
+            const uint32_t probe = 0x03020100;
+            return (((const char*)(&probe))[0]==0x03);
+        #elif __TBB_ENDIANNESS==__TBB_ENDIAN_BIG || __TBB_ENDIANNESS==__TBB_ENDIAN_LITTLE
+            return __TBB_ENDIANNESS==__TBB_ENDIAN_BIG;
+        #else
+            #error Unexpected value of __TBB_ENDIANNESS
+        #endif
+    }};
+
+    const uint32_t byte_offset            = (uint32_t) ((uintptr_t)ptr & 0x3);
+    volatile uint32_t * const aligned_ptr = (uint32_t*)((uintptr_t)ptr - byte_offset );
+
+    // location of T within uint32_t for a C++ shift operation
+    const uint32_t bits_to_shift     = 8*(endianness::is_big_endian() ? (4 - sizeof(T) - (byte_offset)) : byte_offset);
+    const uint32_t mask              = (((uint32_t)1<<(sizeof(T)*8)) - 1 )<<bits_to_shift;
+    // for signed T, any sign extension bits in cast value/comparand are immediately clipped by mask
+    const uint32_t shifted_comparand = ((uint32_t)comparand << bits_to_shift)&mask;
+    const uint32_t shifted_value     = ((uint32_t)value     << bits_to_shift)&mask;
+
+    for( atomic_backoff b;;b.pause() ) {
+        const uint32_t surroundings  = *aligned_ptr & ~mask ; // may have changed during the pause
+        const uint32_t big_comparand = surroundings | shifted_comparand ;
+        const uint32_t big_value     = surroundings | shifted_value     ;
+        // __TBB_machine_cmpswp4 presumed to have full fence.
         // Cast shuts up /Wp64 warning
-        result = (uint32_t)__TBB_machine_cmpswp4( base, new_value, old_value );
-        if(  result==old_value               // CAS succeeded
-          || ((result^old_value)&mask)!=0 )  // CAS failed and the bits of interest have changed
-            break;
-        else                                 // CAS failed but the bits of interest left unchanged
-            b.pause();
+        const uint32_t big_result = (uint32_t)__TBB_machine_cmpswp4( aligned_ptr, big_value, big_comparand );
+        if( big_result == big_comparand                    // CAS succeeded
+          || ((big_result ^ big_comparand) & mask) != 0)   // CAS failed and the bits of interest have changed
+        {
+            return T((big_result & mask) >> bits_to_shift);
+        }
+        else continue;                                     // CAS failed but the bits of interest were not changed
     }
-    return T((result & mask) >> bitoffset);
 }
+#endif // __TBB_ENDIANNESS!=__TBB_ENDIAN_UNSUPPORTED
+////////////////////////////////////////////////////////////////////////////////
 
 template<size_t S, typename T>
 inline T __TBB_CompareAndSwapGeneric (volatile void *ptr, T value, T comparand );
 
 template<>
-inline uint8_t __TBB_CompareAndSwapGeneric <1,uint8_t> (volatile void *ptr, uint8_t value, uint8_t comparand ) {
+inline int8_t __TBB_CompareAndSwapGeneric <1,int8_t> (volatile void *ptr, int8_t value, int8_t comparand ) {
 #if __TBB_USE_GENERIC_PART_WORD_CAS
-    return __TBB_MaskedCompareAndSwap<1,uint8_t>((volatile uint8_t *)ptr,value,comparand);
+    return __TBB_MaskedCompareAndSwap<int8_t>((volatile int8_t *)ptr,value,comparand);
 #else
     return __TBB_machine_cmpswp1(ptr,value,comparand);
 #endif
 }
 
 template<>
-inline uint16_t __TBB_CompareAndSwapGeneric <2,uint16_t> (volatile void *ptr, uint16_t value, uint16_t comparand ) {
+inline int16_t __TBB_CompareAndSwapGeneric <2,int16_t> (volatile void *ptr, int16_t value, int16_t comparand ) {
 #if __TBB_USE_GENERIC_PART_WORD_CAS
-    return __TBB_MaskedCompareAndSwap<2,uint16_t>((volatile uint16_t *)ptr,value,comparand);
+    return __TBB_MaskedCompareAndSwap<int16_t>((volatile int16_t *)ptr,value,comparand);
 #else
     return __TBB_machine_cmpswp2(ptr,value,comparand);
 #endif
 }
 
 template<>
-inline uint32_t __TBB_CompareAndSwapGeneric <4,uint32_t> (volatile void *ptr, uint32_t value, uint32_t comparand ) {
+inline int32_t __TBB_CompareAndSwapGeneric <4,int32_t> (volatile void *ptr, int32_t value, int32_t comparand ) {
     // Cast shuts up /Wp64 warning
-    return (uint32_t)__TBB_machine_cmpswp4(ptr,value,comparand);
+    return (int32_t)__TBB_machine_cmpswp4(ptr,value,comparand);
 }
 
 #if __TBB_64BIT_ATOMICS
 template<>
-inline uint64_t __TBB_CompareAndSwapGeneric <8,uint64_t> (volatile void *ptr, uint64_t value, uint64_t comparand ) {
+inline int64_t __TBB_CompareAndSwapGeneric <8,int64_t> (volatile void *ptr, int64_t value, int64_t comparand ) {
     return __TBB_machine_cmpswp8(ptr,value,comparand);
 }
 #endif
 
 template<size_t S, typename T>
 inline T __TBB_FetchAndAddGeneric (volatile void *ptr, T addend) {
-    atomic_backoff b;
     T result;
-    for(;;) {
+    for( atomic_backoff b;;b.pause() ) {
         result = *reinterpret_cast<volatile T *>(ptr);
         // __TBB_CompareAndSwapGeneric presumed to have full fence.
         if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, result+addend, result )==result )
             break;
-        b.pause();
     }
     return result;
 }
 
 template<size_t S, typename T>
 inline T __TBB_FetchAndStoreGeneric (volatile void *ptr, T value) {
-    atomic_backoff b;
     T result;
-    for(;;) {
+    for( atomic_backoff b;;b.pause() ) {
         result = *reinterpret_cast<volatile T *>(ptr);
         // __TBB_CompareAndSwapGeneric presumed to have full fence.
         if( __TBB_CompareAndSwapGeneric<S,T> ( ptr, value, result )==result )
             break;
-        b.pause();
     }
     return result;
 }
 
 #if __TBB_USE_GENERIC_PART_WORD_CAS
-#define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1,uint8_t>
-#define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2,uint16_t>
+#define __TBB_machine_cmpswp1 tbb::internal::__TBB_CompareAndSwapGeneric<1,int8_t>
+#define __TBB_machine_cmpswp2 tbb::internal::__TBB_CompareAndSwapGeneric<2,int16_t>
 #endif
 
 #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_PART_WORD_FETCH_ADD
-#define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,uint8_t>
-#define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,uint16_t>
+#define __TBB_machine_fetchadd1 tbb::internal::__TBB_FetchAndAddGeneric<1,int8_t>
+#define __TBB_machine_fetchadd2 tbb::internal::__TBB_FetchAndAddGeneric<2,int16_t>
 #endif
 
-#if __TBB_USE_GENERIC_FETCH_ADD 
-#define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,uint32_t>
+#if __TBB_USE_GENERIC_FETCH_ADD
+#define __TBB_machine_fetchadd4 tbb::internal::__TBB_FetchAndAddGeneric<4,int32_t>
 #endif
 
 #if __TBB_USE_GENERIC_FETCH_ADD || __TBB_USE_GENERIC_DWORD_FETCH_ADD
-#define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,uint64_t>
+#define __TBB_machine_fetchadd8 tbb::internal::__TBB_FetchAndAddGeneric<8,int64_t>
 #endif
 
 #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_PART_WORD_FETCH_STORE
-#define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,uint8_t>
-#define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,uint16_t>
+#define __TBB_machine_fetchstore1 tbb::internal::__TBB_FetchAndStoreGeneric<1,int8_t>
+#define __TBB_machine_fetchstore2 tbb::internal::__TBB_FetchAndStoreGeneric<2,int16_t>
 #endif
 
-#if __TBB_USE_GENERIC_FETCH_STORE 
-#define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,uint32_t>
+#if __TBB_USE_GENERIC_FETCH_STORE
+#define __TBB_machine_fetchstore4 tbb::internal::__TBB_FetchAndStoreGeneric<4,int32_t>
 #endif
 
 #if __TBB_USE_GENERIC_FETCH_STORE || __TBB_USE_GENERIC_DWORD_FETCH_STORE
-#define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,uint64_t>
+#define __TBB_machine_fetchstore8 tbb::internal::__TBB_FetchAndStoreGeneric<8,int64_t>
 #endif
 
 #if __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE
@@ -483,28 +579,34 @@ __TBB_MACHINE_DEFINE_ATOMIC_SELECTOR_FETCH_STORE(8)
 #endif /* __TBB_USE_FETCHSTORE_AS_FULL_FENCED_STORE */
 
 #if __TBB_USE_GENERIC_DWORD_LOAD_STORE
-inline void __TBB_machine_store8 (volatile void *ptr, int64_t value) {
-    for(;;) {
-        int64_t result = *(int64_t *)ptr;
-        if( __TBB_machine_cmpswp8(ptr,value,result)==result ) break;
-    }
-}
+/*TODO: find a more elegant way to handle function names difference*/
+#if ! __TBB_USE_FENCED_ATOMICS
+    /* This name forwarding is needed for generic implementation of
+     * load8/store8 defined below (via macro) to pick the right CAS function*/
+    #define   __TBB_machine_cmpswp8full_fence __TBB_machine_cmpswp8
+#endif
+__TBB_MACHINE_DEFINE_LOAD8_GENERIC_FENCED(full_fence)
+__TBB_MACHINE_DEFINE_STORE8_GENERIC_FENCED(full_fence)
 
-inline int64_t __TBB_machine_load8 (const volatile void *ptr) {
-    // Comparand and new value may be anything, they only must be equal, and
-    // the value should have a low probability to be actually found in 'location'.
-    const int64_t anyvalue = 2305843009213693951;
-    return __TBB_machine_cmpswp8(const_cast<volatile void *>(ptr),anyvalue,anyvalue);
-}
+#if ! __TBB_USE_FENCED_ATOMICS
+    #undef   __TBB_machine_cmpswp8full_fence
+#endif
+
+#define __TBB_machine_store8 tbb::internal::__TBB_machine_generic_store8full_fence
+#define __TBB_machine_load8  tbb::internal::__TBB_machine_generic_load8full_fence
 #endif /* __TBB_USE_GENERIC_DWORD_LOAD_STORE */
 
 #if __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE
 /** Fenced operations use volatile qualifier to prevent compiler from optimizing
-    them out, and on on architectures with weak memory ordering to induce compiler
+    them out, and on architectures with weak memory ordering to induce compiler
     to generate code with appropriate acquire/release semantics.
-    On architectures like IA32, Intel64 (and likely and Sparc TSO) volatile has
+    On architectures like IA32, Intel64 (and likely Sparc TSO) volatile has
     no effect on code gen, and consistency helpers serve as a compiler fence (the
-    latter being true for IA64/gcc as well to fix a bug in some gcc versions). **/
+    latter being true for IA64/gcc as well to fix a bug in some gcc versions).
+    This code assumes that the generated instructions will operate atomically,
+    which typically requires a type that can be moved in a single instruction,
+    cooperation from the compiler for effective use of such an instruction,
+    and appropriate alignment of the data. **/
 template <typename T, size_t S>
 struct machine_load_store {
     static T load_with_acquire ( const volatile T& location ) {
@@ -518,6 +620,7 @@ struct machine_load_store {
     }
 };
 
+//in general, plain load and store of 32bit compiler is not atomic for 64bit types
 #if __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS
 template <typename T>
 struct machine_load_store<T,8> {
@@ -531,6 +634,7 @@ struct machine_load_store<T,8> {
 #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */
 #endif /* __TBB_USE_GENERIC_HALF_FENCED_LOAD_STORE */
 
+#if __TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE
 template <typename T, size_t S>
 struct machine_load_store_seq_cst {
     static T load ( const volatile T& location ) {
@@ -557,7 +661,7 @@ struct machine_load_store_seq_cst<T,8> {
     static T load ( const volatile T& location ) {
         // Comparand and new value may be anything, they only must be equal, and
         // the value should have a low probability to be actually found in 'location'.
-        const int64_t anyvalue = 2305843009213693951ll;
+        const int64_t anyvalue = 2305843009213693951LL;
         return __TBB_machine_cmpswp8( (volatile void*)const_cast<volatile T*>(&location), anyvalue, anyvalue );
     }
     static void store ( volatile T &location, T value ) {
@@ -567,11 +671,12 @@ struct machine_load_store_seq_cst<T,8> {
     }
 };
 #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */
+#endif /*__TBB_USE_GENERIC_SEQUENTIAL_CONSISTENCY_LOAD_STORE */
 
 #if __TBB_USE_GENERIC_RELAXED_LOAD_STORE
 // Relaxed operations add volatile qualifier to prevent compiler from optimizing them out.
 /** Volatile should not incur any additional cost on IA32, Intel64, and Sparc TSO
-    architectures. However on architectures with weak memory ordering compiler may 
+    architectures. However on architectures with weak memory ordering compiler may
     generate code with acquire/release semantics for operations on volatile data. **/
 template <typename T, size_t S>
 struct machine_load_store_relaxed {
@@ -596,6 +701,8 @@ struct machine_load_store_relaxed<T,8> {
 #endif /* __TBB_WORDSIZE==4 && __TBB_64BIT_ATOMICS */
 #endif /* __TBB_USE_GENERIC_RELAXED_LOAD_STORE */
 
+#undef __TBB_WORDSIZE //this macro is forbidden to use outside of atomic machinery
+
 template<typename T>
 inline T __TBB_load_with_acquire(const volatile T &location) {
     return machine_load_store<T,sizeof(T)>::load_with_acquire( location );
@@ -635,7 +742,7 @@ inline void __TBB_store_relaxed ( volatile size_t& location, size_t value ) {
     machine_load_store_relaxed<size_t,sizeof(size_t)>::store( const_cast<size_t&>(location), value );
 }
 
-// Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as 
+// Macro __TBB_TypeWithAlignmentAtLeastAsStrict(T) should be a type with alignment at least as
 // strict as type T.  The type should have a trivial default constructor and destructor, so that
 // arrays of that type can be declared without initializers.
 // It is correct (but perhaps a waste of space) if __TBB_TypeWithAlignmentAtLeastAsStrict(T) expands
@@ -685,7 +792,7 @@ template<> struct type_with_alignment<16> {__TBB_machine_type_with_alignment_16
 template<> struct type_with_alignment<32> {__TBB_machine_type_with_alignment_32 member; };
 template<> struct type_with_alignment<64> {__TBB_machine_type_with_alignment_64 member; };
 
-#if __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN  
+#if __TBB_ALIGNOF_NOT_INSTANTIATED_TYPES_BROKEN
 //! Work around for bug in GNU 3.2 and MSVC compilers.
 /** Bug is that compiler sometimes returns 0 for __alignof(T) when T has not yet been instantiated.
     The work-around forces instantiation by forcing computation of sizeof(T) before __alignof(T). */
@@ -727,7 +834,7 @@ const T reverse<T>::byte_table[256] = {
     0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF, 0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
 };
 
-} // namespace internal
+} // namespace internal @endcond
 } // namespace tbb
 
 // Preserving access to legacy APIs
@@ -742,42 +849,50 @@ using tbb::internal::__TBB_store_with_release;
 inline intptr_t __TBB_Log2( uintptr_t x ) {
     if( x==0 ) return -1;
     intptr_t result = 0;
+
+#if !defined(_M_ARM) 
     uintptr_t tmp;
-#if __TBB_WORDSIZE>=8
-    if( (tmp = x>>32) ) { x=tmp; result += 32; }
+    if( sizeof(x)>4 && (tmp = ((uint64_t)x)>>32) ) { x=tmp; result += 32; }
 #endif
-    if( (tmp = x>>16) ) { x=tmp; result += 16; }
-    if( (tmp = x>>8) )  { x=tmp; result += 8; }
-    if( (tmp = x>>4) )  { x=tmp; result += 4; }
-    if( (tmp = x>>2) )  { x=tmp; result += 2; }
+    if( uintptr_t tmp = x>>16 ) { x=tmp; result += 16; }
+    if( uintptr_t tmp = x>>8 )  { x=tmp; result += 8; }
+    if( uintptr_t tmp = x>>4 )  { x=tmp; result += 4; }
+    if( uintptr_t tmp = x>>2 )  { x=tmp; result += 2; }
+
     return (x&2)? result+1: result;
 }
 #endif
 
 #ifndef __TBB_AtomicOR
 inline void __TBB_AtomicOR( volatile void *operand, uintptr_t addend ) {
-    tbb::internal::atomic_backoff b;
-    for(;;) {
+    for( tbb::internal::atomic_backoff b;;b.pause() ) {
         uintptr_t tmp = *(volatile uintptr_t *)operand;
         uintptr_t result = __TBB_CompareAndSwapW(operand, tmp|addend, tmp);
         if( result==tmp ) break;
-        b.pause();
     }
 }
 #endif
 
 #ifndef __TBB_AtomicAND
 inline void __TBB_AtomicAND( volatile void *operand, uintptr_t addend ) {
-    tbb::internal::atomic_backoff b;
-    for(;;) {
+    for( tbb::internal::atomic_backoff b;;b.pause() ) {
         uintptr_t tmp = *(volatile uintptr_t *)operand;
         uintptr_t result = __TBB_CompareAndSwapW(operand, tmp&addend, tmp);
         if( result==tmp ) break;
-        b.pause();
     }
 }
 #endif
 
+#if __TBB_PREFETCHING
+#ifndef __TBB_cl_prefetch
+#error This platform does not define cache management primitives required for __TBB_PREFETCHING
+#endif
+
+#ifndef __TBB_cl_evict
+#define __TBB_cl_evict(p)
+#endif
+#endif
+
 #ifndef __TBB_Flag
 typedef unsigned char __TBB_Flag;
 #endif
@@ -791,17 +906,45 @@ inline bool __TBB_TryLockByte( __TBB_atomic_flag &flag ) {
 
 #ifndef __TBB_LockByte
 inline __TBB_Flag __TBB_LockByte( __TBB_atomic_flag& flag ) {
-    if ( !__TBB_TryLockByte(flag) ) {
-        tbb::internal::atomic_backoff b;
-        do {
-            b.pause();
-        } while ( !__TBB_TryLockByte(flag) );
-    }
+    tbb::internal::atomic_backoff backoff;
+    while( !__TBB_TryLockByte(flag) ) backoff.pause();
     return 0;
 }
 #endif
 
-#define __TBB_UnlockByte __TBB_store_with_release
+#ifndef  __TBB_UnlockByte
+#define __TBB_UnlockByte(addr) __TBB_store_with_release((addr),0)
+#endif
+
+// lock primitives with TSX
+#if ( __TBB_x86_32 || __TBB_x86_64 )  /* only on ia32/intel64 */
+inline void __TBB_TryLockByteElidedCancel() { __TBB_machine_try_lock_elided_cancel(); }
+
+inline bool __TBB_TryLockByteElided( __TBB_atomic_flag& flag ) {
+    bool res = __TBB_machine_try_lock_elided( &flag )!=0;
+    // to avoid the "lemming" effect, we need to abort the transaction
+    // if  __TBB_machine_try_lock_elided returns false (i.e., someone else
+    // has acquired the mutex non-speculatively).
+    if( !res ) __TBB_TryLockByteElidedCancel();
+    return res;
+}
+
+inline void __TBB_LockByteElided( __TBB_atomic_flag& flag )
+{
+    for(;;) {
+        tbb::internal::spin_wait_while_eq( flag, 1 );
+        if( __TBB_machine_try_lock_elided( &flag ) )
+            return;
+        // Another thread acquired the lock "for real".
+        // To avoid the "lemming" effect, we abort the transaction.
+        __TBB_TryLockByteElidedCancel();
+    }
+}
+
+inline void __TBB_UnlockByteElided( __TBB_atomic_flag& flag ) {
+    __TBB_machine_unlock_elided( &flag );
+}
+#endif
 
 #ifndef __TBB_ReverseByte
 inline unsigned char __TBB_ReverseByte(unsigned char src) {
index a56039fbeae587a7be4becbc6efe6af30d93a410..5a0830f751d5fda0973b3b89d5ad7ce4a5e373f9 100644 (file)
@@ -1,34 +1,56 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_profiling_H
 #define __TBB_profiling_H
 
+namespace tbb {
+    namespace internal {
+
+        //
+        // This is not under __TBB_ITT_STRUCTURE_API because these values are used directly in flow_graph.h.  
+        //
+       
+        // include list of index names
+        #define TBB_STRING_RESOURCE(index_name,str) index_name,
+        enum string_index {
+           #include "internal/_tbb_strings.h"
+           NUM_STRINGS
+        };
+        #undef TBB_STRING_RESOURCE
+
+        enum itt_relation
+        {
+        __itt_relation_is_unknown = 0,
+        __itt_relation_is_dependent_on,         /**< "A is dependent on B" means that A cannot start until B completes */
+        __itt_relation_is_sibling_of,           /**< "A is sibling of B" means that A and B were created as a group */
+        __itt_relation_is_parent_of,            /**< "A is parent of B" means that A created B */
+        __itt_relation_is_continuation_of,      /**< "A is continuation of B" means that A assumes the dependencies of B */
+        __itt_relation_is_child_of,             /**< "A is child of B" means that A was created by B (inverse of is_parent_of) */
+        __itt_relation_is_continued_by,         /**< "A is continued by B" means that B assumes the dependencies of A (inverse of is_continuation_of) */
+        __itt_relation_is_predecessor_to        /**< "A is predecessor to B" means that B cannot start until A completes (inverse of is_dependent_on) */
+        };
+    
+    }
+}
+
 // Check if the tools support is enabled
 #if (_WIN32||_WIN64||__linux__) && !__MINGW32__ && TBB_USE_THREADING_TOOLS
 
@@ -39,8 +61,9 @@
 
 namespace tbb {
     namespace internal {
+
 #if _WIN32||_WIN64
-        void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name ); 
+        void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const wchar_t* name );
         inline size_t multibyte_to_widechar( wchar_t* wcs, const char* mbs, size_t bufsize) {
 #if _MSC_VER>=1400
             size_t len;
@@ -54,16 +77,16 @@ namespace tbb {
 #endif
         }
 #else
-        void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const char* name ); 
+        void __TBB_EXPORTED_FUNC itt_set_sync_name_v3( void *obj, const char* name );
 #endif
     } // namespace internal
 } // namespace tbb
 
 //! Macro __TBB_DEFINE_PROFILING_SET_NAME(T) defines "set_name" methods for sync objects of type T
-/** Should be used in the "tbb" namespace only. 
+/** Should be used in the "tbb" namespace only.
     Don't place semicolon after it to avoid compiler warnings. **/
 #if _WIN32||_WIN64
-    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)    \
+    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)                       \
         namespace profiling {                                                       \
             inline void set_name( sync_object_type& obj, const wchar_t* name ) {    \
                 tbb::internal::itt_set_sync_name_v3( &obj, name );                  \
@@ -77,7 +100,7 @@ namespace tbb {
             }                                                                       \
         }
 #else /* !WIN */
-    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)    \
+    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)                       \
         namespace profiling {                                                       \
             inline void set_name( sync_object_type& obj, const char* name ) {       \
                 tbb::internal::itt_set_sync_name_v3( &obj, name );                  \
@@ -88,13 +111,13 @@ namespace tbb {
 #else /* no tools support */
 
 #if _WIN32||_WIN64
-    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)    \
+    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)               \
         namespace profiling {                                               \
             inline void set_name( sync_object_type&, const wchar_t* ) {}    \
             inline void set_name( sync_object_type&, const char* ) {}       \
         }
 #else /* !WIN */
-    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)    \
+    #define __TBB_DEFINE_PROFILING_SET_NAME(sync_object_type)               \
         namespace profiling {                                               \
             inline void set_name( sync_object_type&, const char* ) {}       \
         }
@@ -108,12 +131,26 @@ namespace tbb {
     namespace internal {
 
         enum notify_type {prepare=0, cancel, acquired, releasing};
+
         const uintptr_t NUM_NOTIFY_TYPES = 4; // set to # elements in enum above
-        
+
         void __TBB_EXPORTED_FUNC call_itt_notify_v5(int t, void *ptr);
         void __TBB_EXPORTED_FUNC itt_store_pointer_with_release_v3(void *dst, void *src);
         void* __TBB_EXPORTED_FUNC itt_load_pointer_with_acquire_v3(const void *src);
         void* __TBB_EXPORTED_FUNC itt_load_pointer_v3( const void* src );
+#if __TBB_ITT_STRUCTURE_API
+        enum itt_domain_enum { ITT_DOMAIN_FLOW=0 };
+
+        void __TBB_EXPORTED_FUNC itt_make_task_group_v7( itt_domain_enum domain, void *group, unsigned long long group_extra, 
+                                                         void *parent, unsigned long long parent_extra, string_index name_index ); 
+        void __TBB_EXPORTED_FUNC itt_metadata_str_add_v7( itt_domain_enum domain, void *addr, unsigned long long addr_extra, 
+                                                          string_index key, const char *value ); 
+        void __TBB_EXPORTED_FUNC itt_relation_add_v7( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, 
+                                                      itt_relation relation, void *addr1, unsigned long long addr1_extra );
+        void __TBB_EXPORTED_FUNC itt_task_begin_v7( itt_domain_enum domain, void *task, unsigned long long task_extra, 
+                                                    void *parent, unsigned long long parent_extra, string_index name_index );
+        void __TBB_EXPORTED_FUNC itt_task_end_v7( itt_domain_enum domain );
+#endif // __TBB_ITT_STRUCTURE_API
 
         // two template arguments are to workaround /Wp64 warning with tbb::atomic specialized for unsigned type
         template <typename T, typename U>
@@ -133,7 +170,7 @@ namespace tbb {
             // This assertion should be replaced with static_assert
             __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized.");
 #if defined(_MSC_VER) && !defined(__INTEL_COMPILER)
-            // Workaround for overzealous compiler warnings 
+            // Workaround for overzealous compiler warnings
             #pragma warning (push)
             #pragma warning (disable: 4311)
 #endif
@@ -168,11 +205,11 @@ namespace tbb {
             return __TBB_load_with_acquire(src);
 #endif // TBB_USE_THREADING_TOOLS
         }
-        
+
         template <typename T>
         inline void itt_hide_store_word(T& dst, T src) {
 #if TBB_USE_THREADING_TOOLS
-            // This assertion should be replaced with static_assert
+            //TODO: This assertion should be replaced with static_assert
             __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized");
             itt_store_pointer_with_release_v3(&dst, (void *)src);
 #else
@@ -180,10 +217,11 @@ namespace tbb {
 #endif
         }
 
+        //TODO: rename to itt_hide_load_word_relaxed
         template <typename T>
         inline T itt_hide_load_word(const T& src) {
 #if TBB_USE_THREADING_TOOLS
-            // This assertion should be replaced with static_assert
+            //TODO: This assertion should be replaced with static_assert
             __TBB_ASSERT(sizeof(T) == sizeof(void *), "Type must be word-sized.");
             return (T)itt_load_pointer_v3(&src);
 #else
@@ -195,10 +233,38 @@ namespace tbb {
         inline void call_itt_notify(notify_type t, void *ptr) {
             call_itt_notify_v5((int)t, ptr);
         }
+
 #else
         inline void call_itt_notify(notify_type /*t*/, void * /*ptr*/) {}
+
 #endif // TBB_USE_THREADING_TOOLS
 
+#if __TBB_ITT_STRUCTURE_API
+        inline void itt_make_task_group( itt_domain_enum domain, void *group, unsigned long long group_extra, 
+                                         void *parent, unsigned long long parent_extra, string_index name_index ) {
+            itt_make_task_group_v7( domain, group, group_extra, parent, parent_extra, name_index ); 
+        }
+
+        inline void itt_metadata_str_add( itt_domain_enum domain, void *addr, unsigned long long addr_extra, 
+                                          string_index key, const char *value ) {
+            itt_metadata_str_add_v7( domain, addr, addr_extra, key, value ); 
+        }
+
+        inline void itt_relation_add( itt_domain_enum domain, void *addr0, unsigned long long addr0_extra, 
+                                      itt_relation relation, void *addr1, unsigned long long addr1_extra ) {
+            itt_relation_add_v7( domain, addr0, addr0_extra, relation, addr1, addr1_extra );
+        }
+
+        inline void itt_task_begin( itt_domain_enum domain, void *task, unsigned long long task_extra, 
+                                                        void *parent, unsigned long long parent_extra, string_index name_index ) {
+            itt_task_begin_v7( domain, task, task_extra, parent, parent_extra, name_index );
+        }
+
+        inline void itt_task_end( itt_domain_enum domain ) {
+            itt_task_end_v7( domain );
+        }
+#endif // __TBB_ITT_STRUCTURE_API
+
     } // namespace internal
 } // namespace tbb
 
index 7b255553aba8a5fc5d344006b884d04bb2c0d41c..274a32947a530a08b3bc4c95656b5b3cb65d2c30 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tbb_stddef_H
 
 // Marketing-driven product version
 #define TBB_VERSION_MAJOR 4
-#define TBB_VERSION_MINOR 0
+#define TBB_VERSION_MINOR 3
 
 // Engineering-focused interface version
-#define TBB_INTERFACE_VERSION 6000
+#define TBB_INTERFACE_VERSION 8002
 #define TBB_INTERFACE_VERSION_MAJOR TBB_INTERFACE_VERSION/1000
 
 // The oldest major interface version still supported
@@ -62,7 +54,7 @@
  * \mainpage Main Page
  *
  * Click the tabs above for information about the
- * - <a href="./modules.html">Modules</a> (groups of functionality) implemented by the library 
+ * - <a href="./modules.html">Modules</a> (groups of functionality) implemented by the library
  * - <a href="./annotated.html">Classes</a> provided by the library
  * - <a href="./files.html">Files</a> constituting the library.
  * .
  */
 
 /** \page concepts TBB concepts
-    
+
     A concept is a set of requirements to a type, which are necessary and sufficient
-    for the type to model a particular behavior or a set of behaviors. Some concepts 
-    are specific to a particular algorithm (e.g. algorithm body), while other ones 
-    are common to several algorithms (e.g. range concept). 
+    for the type to model a particular behavior or a set of behaviors. Some concepts
+    are specific to a particular algorithm (e.g. algorithm body), while other ones
+    are common to several algorithms (e.g. range concept).
 
     All TBB algorithms make use of different classes implementing various concepts.
-    Implementation classes are supplied by the user as type arguments of template 
-    parameters and/or as objects passed as function call arguments. The library 
-    provides predefined  implementations of some concepts (e.g. several kinds of 
-    \ref range_req "ranges"), while other ones must always be implemented by the user. 
-    
-    TBB defines a set of minimal requirements each concept must conform to. Here is 
+    Implementation classes are supplied by the user as type arguments of template
+    parameters and/or as objects passed as function call arguments. The library
+    provides predefined  implementations of some concepts (e.g. several kinds of
+    \ref range_req "ranges"), while other ones must always be implemented by the user.
+
+    TBB defines a set of minimal requirements each concept must conform to. Here is
     the list of different concepts hyperlinked to the corresponding requirements specifications:
     - \subpage range_req
     - \subpage parallel_do_body_req
     - \subpage parallel_sort_iter_req
 **/
 
-// Define preprocessor symbols used to determine architecture
-#if _WIN32||_WIN64
-#   if defined(_M_X64)||defined(__x86_64__)  // the latter for MinGW support
-#       define __TBB_x86_64 1
-#   elif defined(_M_IA64)
-#       define __TBB_ipf 1
-#   elif defined(_M_IX86)||defined(__i386__) // the latter for MinGW support
-#       define __TBB_x86_32 1
-#   endif
-#else /* Assume generic Unix */
-#   if !__linux__ && !__APPLE__
-#       define __TBB_generic_os 1
-#   endif
-#   if __x86_64__
-#       define __TBB_x86_64 1
-#   elif __ia64__
-#       define __TBB_ipf 1
-#   elif __i386__||__i386  // __i386 is for Sun OS
-#       define __TBB_x86_32 1
-#   else
-#       define __TBB_generic_arch 1
-#   endif
-#endif
-
 // tbb_config.h should be included the first since it contains macro definitions used in other headers
 #include "tbb_config.h"
 
     #define __TBB_EXPORTED_METHOD
 #endif
 
+#if __INTEL_COMPILER || _MSC_VER
+#define __TBB_NOINLINE(decl) __declspec(noinline) decl
+#elif __GNUC__
+#define __TBB_NOINLINE(decl) decl __attribute__ ((noinline))
+#else
+#define __TBB_NOINLINE(decl) decl
+#endif
+
+#if __TBB_NOEXCEPT_PRESENT
+#define __TBB_NOEXCEPT(expression) noexcept(expression)
+#else
+#define __TBB_NOEXCEPT(expression)
+#endif
+
 #include <cstddef>      /* Need size_t and ptrdiff_t */
 
 #if _MSC_VER
     #define __TBB_tbb_windef_H
     #include "internal/_tbb_windef.h"
     #undef __TBB_tbb_windef_H
-#else
+#endif
+#if !defined(_MSC_VER) || _MSC_VER>=1600
     #include <stdint.h>
 #endif
 
+//! Type for an assertion handler
+typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment );
+
+#if TBB_USE_ASSERT
+
+     #define __TBB_ASSERT_NS(predicate,message,ns) ((predicate)?((void)0) : ns::assertion_failure(__FILE__,__LINE__,#predicate,message))
+    //! Assert that x is true.
+    /** If x is false, print assertion failure message.
+        If the comment argument is not NULL, it is printed as part of the failure message.
+        The comment argument has no other effect. */
+#if __TBBMALLOC_BUILD
+namespace rml { namespace internal {
+    #define __TBB_ASSERT(predicate,message) __TBB_ASSERT_NS(predicate,message,rml::internal)
+#else
+namespace tbb {
+    #define __TBB_ASSERT(predicate,message) __TBB_ASSERT_NS(predicate,message,tbb)
+#endif
+
+    #define __TBB_ASSERT_EX __TBB_ASSERT
+
+    //! Set assertion handler and return previous value of it.
+    assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler );
+
+    //! Process an assertion failure.
+    /** Normally called from __TBB_ASSERT macro.
+        If assertion handler is null, print message for assertion failure and abort.
+        Otherwise call the assertion handler. */
+    void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment );
+
+#if __TBBMALLOC_BUILD
+}}  // namespace rml::internal
+#else
+} // namespace tbb
+#endif
+#else /* !TBB_USE_ASSERT */
+
+    //! No-op version of __TBB_ASSERT.
+    #define __TBB_ASSERT(predicate,comment) ((void)0)
+    //! "Extended" version is useful to suppress warnings if a variable is only used with an assert
+    #define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate)))
+
+#endif /* !TBB_USE_ASSERT */
+
 //! The namespace tbb contains all components of the library.
 namespace tbb {
 
-#if _MSC_VER
+#if _MSC_VER && _MSC_VER<1600
     namespace internal {
         typedef __int8 int8_t;
         typedef __int16 int16_t;
@@ -174,36 +200,6 @@ namespace tbb {
     using std::size_t;
     using std::ptrdiff_t;
 
-    //! Type for an assertion handler
-    typedef void(*assertion_handler_type)( const char* filename, int line, const char* expression, const char * comment );
-
-#if TBB_USE_ASSERT
-
-    //! Assert that x is true.
-    /** If x is false, print assertion failure message.  
-        If the comment argument is not NULL, it is printed as part of the failure message.  
-        The comment argument has no other effect. */
-    #define __TBB_ASSERT(predicate,message) ((predicate)?((void)0):tbb::assertion_failure(__FILE__,__LINE__,#predicate,message))
-    #define __TBB_ASSERT_EX __TBB_ASSERT
-
-    //! Set assertion handler and return previous value of it.
-    assertion_handler_type __TBB_EXPORTED_FUNC set_assertion_handler( assertion_handler_type new_handler );
-
-    //! Process an assertion failure.
-    /** Normally called from __TBB_ASSERT macro.
-        If assertion handler is null, print message for assertion failure and abort.
-        Otherwise call the assertion handler. */
-    void __TBB_EXPORTED_FUNC assertion_failure( const char* filename, int line, const char* expression, const char* comment );
-
-#else /* !TBB_USE_ASSERT */
-
-    //! No-op version of __TBB_ASSERT.
-    #define __TBB_ASSERT(predicate,comment) ((void)0)
-    //! "Extended" version is useful to suppress warnings if a variable is only used with an assert
-    #define __TBB_ASSERT_EX(predicate,comment) ((void)(1 && (predicate)))
-
-#endif /* !TBB_USE_ASSERT */
-
 //! The function returns the interface version of the TBB shared library being used.
 /**
  * The version it returns is determined at runtime, not at compile/link time.
@@ -211,14 +207,6 @@ namespace tbb {
  */
 extern "C" int __TBB_EXPORTED_FUNC TBB_runtime_interface_version();
 
-//! Dummy type that distinguishes splitting constructor from copy constructor.
-/**
- * See description of parallel_for and parallel_reduce for example usages.
- * @ingroup algorithms
- */
-class split {
-};
-
 /**
  * @cond INTERNAL
  * @brief Identifiers declared inside namespace internal should never be used directly by client code.
@@ -226,14 +214,14 @@ class split {
 namespace internal {
 
 //! Compile-time constant that is upper bound on cache line/sector size.
-/** It should be used only in situations where having a compile-time upper 
+/** It should be used only in situations where having a compile-time upper
     bound is more useful than a run-time exact answer.
     @ingroup memory_allocation */
 const size_t NFS_MaxLineSize = 128;
 
 /** Label for data that may be accessed from different threads, and that may eventually become wrapped
     in a formal atomic type.
-    
+
     Note that no problems have yet been observed relating to the definition currently being empty,
     even if at least "volatile" would seem to be in order to avoid data sometimes temporarily hiding
     in a register (although "volatile" as a "poor man's atomic" lacks several other features of a proper
@@ -243,7 +231,7 @@ const size_t NFS_MaxLineSize = 128;
     both as a way to have the compiler help enforce use of the label and to quickly rule out
     one potential issue.
 
-    Note however that, with some architecture/compiler combinations, e.g. on Itanium, "volatile" 
+    Note however that, with some architecture/compiler combinations, e.g. on IA-64 architecture, "volatile"
     also has non-portable memory semantics that are needlessly expensive for "relaxed" operations.
 
     Note that this must only be applied to data that will not change bit patterns when cast to/from
@@ -252,15 +240,15 @@ const size_t NFS_MaxLineSize = 128;
     TODO: apply wherever relevant **/
 #define __TBB_atomic // intentionally empty, see above
 
-template<class T, int S>
+template<class T, size_t S, size_t R>
 struct padded_base : T {
-    char pad[NFS_MaxLineSize - sizeof(T) % NFS_MaxLineSize];
+    char pad[S - R];
 };
-template<class T> struct padded_base<T, 0> : T {};
+template<class T, size_t S> struct padded_base<T, S, 0> : T {};
 
 //! Pads type T to fill out to a multiple of cache line size.
-template<class T>
-struct padded : padded_base<T, sizeof(T)> {};
+template<class T, size_t S = NFS_MaxLineSize>
+struct padded : padded_base<T, S, sizeof(T) % S> {};
 
 //! Extended variant of the standard offsetof macro
 /** The standard offsetof macro is not sufficient for TBB as it can be used for
@@ -295,21 +283,24 @@ void __TBB_EXPORTED_FUNC runtime_warning( const char* format, ... );
 static void* const poisoned_ptr = reinterpret_cast<void*>(-1);
 
 //! Set p to invalid pointer value.
+//  Also works for regular (non-__TBB_atomic) pointers.
 template<typename T>
-inline void poison_pointer( T*& p ) { p = reinterpret_cast<T*>(poisoned_ptr); }
+inline void poison_pointer( T* __TBB_atomic & p ) { p = reinterpret_cast<T*>(poisoned_ptr); }
 
 /** Expected to be used in assertions only, thus no empty form is defined. **/
 template<typename T>
 inline bool is_poisoned( T* p ) { return p == reinterpret_cast<T*>(poisoned_ptr); }
 #else
 template<typename T>
-inline void poison_pointer( T* ) {/*do nothing*/}
+inline void poison_pointer( T* __TBB_atomic & ) {/*do nothing*/}
 #endif /* !TBB_USE_ASSERT */
 
-//! Cast pointer from U* to T.
-/** This method should be used sparingly as a last resort for dealing with 
+//! Cast between unrelated pointer types.
+/** This method should be used sparingly as a last resort for dealing with
     situations that inherently break strict ISO C++ aliasing rules. */
-template<typename T, typename U> 
+// T is a pointer type because it will be explicitly provided by the programmer as a template argument;
+// U is a referent type to enable the compiler to check that "ptr" is a pointer, deducing U in the process.
+template<typename T, typename U>
 inline T punned_cast( U* ptr ) {
     uintptr_t x = reinterpret_cast<uintptr_t>(ptr);
     return reinterpret_cast<T>(x);
@@ -335,6 +326,110 @@ public:
     no_copy() {}
 };
 
+#if TBB_DEPRECATED_MUTEX_COPYING
+class mutex_copy_deprecated_and_disabled {};
+#else
+// By default various implementations of mutexes are not copy constructible
+// and not copy assignable.
+class mutex_copy_deprecated_and_disabled : no_copy {};
+#endif
+
+//! A function to check if passed in pointer is aligned on a specific border
+template<typename T>
+inline bool is_aligned(T* pointer, uintptr_t alignment) {
+    return 0==((uintptr_t)pointer & (alignment-1));
+}
+
+//! A function to check if passed integer is a power of 2
+template<typename integer_type>
+inline bool is_power_of_two(integer_type arg) {
+    return arg && (0 == (arg & (arg - 1)));
+}
+
+//! A function to compute arg modulo divisor where divisor is a power of 2.
+template<typename argument_integer_type, typename divisor_integer_type>
+inline argument_integer_type modulo_power_of_two(argument_integer_type arg, divisor_integer_type divisor) {
+    // Divisor is assumed to be a power of two (which is valid for current uses).
+    __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of two" );
+    return (arg & (divisor - 1));
+}
+
+
+//! A function to determine if "arg is a multiplication of a number and a power of 2".
+// i.e. for strictly positive i and j, with j a power of 2,
+// determines whether i==j<<k for some nonnegative k (so i==j yields true).
+template<typename argument_integer_type, typename divisor_integer_type>
+inline bool is_power_of_two_factor(argument_integer_type arg, divisor_integer_type divisor) {
+    // Divisor is assumed to be a power of two (which is valid for current uses).
+    __TBB_ASSERT( is_power_of_two(divisor), "Divisor should be a power of two" );
+    return 0 == (arg & (arg - divisor));
+}
+
+//! Utility template function to prevent "unused" warnings by various compilers.
+template<typename T1> void suppress_unused_warning( const T1& ) {}
+template<typename T1, typename T2> void suppress_unused_warning( const T1&, const T2& ) {}
+template<typename T1, typename T2, typename T3> void suppress_unused_warning( const T1&, const T2&, const T3& ) {}
+
+// Struct to be used as a version tag for inline functions.
+/** Version tag can be necessary to prevent loader on Linux from using the wrong
+    symbol in debug builds (when inline functions are compiled as out-of-line). **/
+struct version_tag_v3 {};
+
+typedef version_tag_v3 version_tag;
+
+} // internal
+
+//! Dummy type that distinguishes splitting constructor from copy constructor.
+/**
+ * See description of parallel_for and parallel_reduce for example usages.
+ * @ingroup algorithms
+ */
+class split {
+};
+
+//! Type enables transmission of splitting proportion from partitioners to range objects
+/**
+ * In order to make use of such facility Range objects must implement
+ * splitting constructor with this type passed and initialize static
+ * constant boolean field 'is_splittable_in_proportion' with the value
+ * of 'true'
+ */
+class proportional_split: internal::no_assign {
+public:
+    proportional_split(size_t _left = 1, size_t _right = 1) : my_left(_left), my_right(_right) { }
+
+    size_t left() const { return my_left; }
+    size_t right() const { return my_right; }
+
+    // used when range does not support proportional split
+    operator split() const { return split(); }
+
+#if __TBB_ENABLE_RANGE_FEEDBACK
+    void set_proportion(size_t _left, size_t _right) {
+        my_left = _left;
+        my_right = _right;
+    }
+#endif
+private:
+    size_t my_left, my_right;
+};
+
+} // tbb
+
+// Following is a set of classes and functions typically used in compile-time "metaprogramming".
+// TODO: move all that to a separate header
+
+#if __TBB_ALLOCATOR_TRAITS_PRESENT
+#include <memory> //for allocator_traits
+#endif
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT || _LIBCPP_VERSION
+#include <utility> // for std::move
+#endif
+
+namespace tbb {
+namespace internal {
+
 //! Class for determining type of std::allocator<T>::value_type.
 template<typename T>
 struct allocator_type {
@@ -342,24 +437,72 @@ struct allocator_type {
 };
 
 #if _MSC_VER
-//! Microsoft std::allocator has non-standard extension that strips const from a type. 
+//! Microsoft std::allocator has non-standard extension that strips const from a type.
 template<typename T>
 struct allocator_type<const T> {
     typedef T value_type;
 };
 #endif
 
-// Struct to be used as a version tag for inline functions.
-/** Version tag can be necessary to prevent loader on Linux from using the wrong 
-    symbol in debug builds (when inline functions are compiled as out-of-line). **/
-struct version_tag_v3 {};
+// Ad-hoc implementation of true_type & false_type
+// Intended strictly for internal use! For public APIs (traits etc), use C++11 analogues.
+template <bool v>
+struct bool_constant {
+    static /*constexpr*/ const bool value = v;
+};
+typedef bool_constant<true> true_type;
+typedef bool_constant<false> false_type;
 
-typedef version_tag_v3 version_tag;
+#if __TBB_ALLOCATOR_TRAITS_PRESENT
+using std::allocator_traits;
+#else
+template<typename allocator>
+struct allocator_traits{
+    typedef tbb::internal::false_type propagate_on_container_move_assignment;
+};
+#endif
+
+//! A template to select either 32-bit or 64-bit constant as compile time, depending on machine word size.
+template <unsigned u, unsigned long long ull >
+struct select_size_t_constant {
+    //Explicit cast is needed to avoid compiler warnings about possible truncation.
+    //The value of the right size,   which is selected by ?:, is anyway not truncated or promoted.
+    static const size_t value = (size_t)((sizeof(size_t)==sizeof(u)) ? u : ull);
+};
+
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+using std::move;
+#elif defined(_LIBCPP_NAMESPACE)
+// libc++ defines "pre-C++11 move" similarly to our; use it to avoid name conflicts in some cases.
+using std::_LIBCPP_NAMESPACE::move;
+#else
+template <typename T>
+T& move( T& x ) { return x; }
+#endif
+
+template <bool condition>
+struct STATIC_ASSERTION_FAILED;
+
+template <>
+struct STATIC_ASSERTION_FAILED<false> { enum {value=1};};
+
+template<>
+struct STATIC_ASSERTION_FAILED<true>; //intentionally left undefined to cause compile time error
 
-} // internal
 //! @endcond
+}} // namespace tbb::internal
 
-} // tbb
+#if    __TBB_STATIC_ASSERT_PRESENT
+#define __TBB_STATIC_ASSERT(condition,msg) static_assert(condition,msg)
+#else
+//please note condition is intentionally inverted to get a bit more understandable error msg
+#define __TBB_STATIC_ASSERT_IMPL1(condition,msg,line)       \
+    enum {static_assert_on_line_##line = tbb::internal::STATIC_ASSERTION_FAILED<!(condition)>::value}
+
+#define __TBB_STATIC_ASSERT_IMPL(condition,msg,line) __TBB_STATIC_ASSERT_IMPL1(condition,msg,line)
+//! Verify at compile time that passed in condition is hold
+#define __TBB_STATIC_ASSERT(condition,msg) __TBB_STATIC_ASSERT_IMPL(condition,msg,__LINE__)
+#endif
 
 #endif /* RC_INVOKED */
 #endif /* __TBB_tbb_stddef_H */
index 5e71132c42efd5ce76c75992c7c3870a04abba29..00ec2470998342f47df4130a8acadef6d23838b6 100644 (file)
@@ -1,45 +1,42 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tbb_thread_H
 #define __TBB_tbb_thread_H
 
+#include "tbb_stddef.h"
 #if _WIN32||_WIN64
 #include "machine/windows_api.h"
 #define __TBB_NATIVE_THREAD_ROUTINE unsigned WINAPI
 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) unsigned (WINAPI* r)( void* )
+#if __TBB_WIN8UI_SUPPORT
+typedef size_t thread_id_type;
+#else  // __TBB_WIN8UI_SUPPORT
+typedef DWORD thread_id_type;
+#endif // __TBB_WIN8UI_SUPPORT
 #else
 #define __TBB_NATIVE_THREAD_ROUTINE void*
 #define __TBB_NATIVE_THREAD_ROUTINE_PTR(r) void* (*r)( void* )
 #include <pthread.h>
 #endif // _WIN32||_WIN64
 
-#include "tbb_stddef.h"
 #include "tick_count.h"
 
 #if !TBB_USE_EXCEPTIONS && _MSC_VER
 
 namespace tbb {
 
-//! @cond INTERNAL
 namespace internal {
-    
     class tbb_thread_v3;
+}
 
-} // namespace internal
-
-inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ); 
+inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true);
 
 namespace internal {
 
@@ -117,6 +111,12 @@ namespace internal {
 
     //! Versioned thread class.
     class tbb_thread_v3 {
+#if __TBB_IF_NO_COPY_CTOR_MOVE_SEMANTICS_BROKEN
+        // Workaround for a compiler bug: declaring the copy constructor as public
+        // enables use of the moving constructor.
+        // The definition is not provided in order to prohibit copying.
+    public:
+#endif
         tbb_thread_v3(const tbb_thread_v3&); // = delete;   // Deny access
     public:
 #if _WIN32||_WIN64
@@ -127,7 +127,7 @@ namespace internal {
 
         class id;
         //! Constructs a thread object that does not represent a thread of execution. 
-        tbb_thread_v3() : my_handle(0)
+        tbb_thread_v3() __TBB_NOEXCEPT(true) : my_handle(0)
 #if _WIN32||_WIN64
             , my_thread_id(0)
 #endif // _WIN32||_WIN64
@@ -149,24 +149,37 @@ namespace internal {
             internal_start(closure_type::start_routine, new closure_type(f,x,y));
         }
 
-        tbb_thread_v3& operator=(tbb_thread_v3& x) {
-            if (joinable()) detach();
-            my_handle = x.my_handle;
-            x.my_handle = 0;
+#if __TBB_CPP11_RVALUE_REF_PRESENT
+        tbb_thread_v3(tbb_thread_v3&& x) __TBB_NOEXCEPT(true)
+            : my_handle(x.my_handle)
 #if _WIN32||_WIN64
-            my_thread_id = x.my_thread_id;
-            x.my_thread_id = 0;
-#endif // _WIN32||_WIN64
+            , my_thread_id(x.my_thread_id)
+#endif
+        {
+            x.internal_wipe();
+        }
+        tbb_thread_v3& operator=(tbb_thread_v3&& x) __TBB_NOEXCEPT(true) {
+            internal_move(x);
             return *this;
         }
-        void swap( tbb_thread_v3& t ) {tbb::swap( *this, t );}
-        bool joinable() const {return my_handle!=0; }
+    private:
+        tbb_thread_v3& operator=(const tbb_thread_v3& x); // = delete;
+    public:
+#else  // __TBB_CPP11_RVALUE_REF_PRESENT
+        tbb_thread_v3& operator=(tbb_thread_v3& x) {
+            internal_move(x);
+            return *this;
+        }
+#endif // __TBB_CPP11_RVALUE_REF_PRESENT
+
+        void swap( tbb_thread_v3& t ) __TBB_NOEXCEPT(true) {tbb::swap( *this, t );}
+        bool joinable() const __TBB_NOEXCEPT(true) {return my_handle!=0; }
         //! The completion of the thread represented by *this happens before join() returns.
         void __TBB_EXPORTED_METHOD join();
         //! When detach() returns, *this no longer represents the possibly continuing thread of execution.
         void __TBB_EXPORTED_METHOD detach();
         ~tbb_thread_v3() {if( joinable() ) detach();}
-        inline id get_id() const;
+        inline id get_id() const __TBB_NOEXCEPT(true);
         native_handle_type native_handle() { return my_handle; }
     
         //! The number of hardware thread contexts.
@@ -179,38 +192,53 @@ namespace internal {
             invocation. This means that changes in the process affinity mask that
             took place after this method was first invoked will not affect the
             number of worker threads in the TBB worker threads pool. **/
-        static unsigned __TBB_EXPORTED_FUNC hardware_concurrency();
+        static unsigned __TBB_EXPORTED_FUNC hardware_concurrency() __TBB_NOEXCEPT(true);
     private:
         native_handle_type my_handle; 
 #if _WIN32||_WIN64
-        DWORD my_thread_id;
+        thread_id_type my_thread_id;
 #endif // _WIN32||_WIN64
 
+        void internal_wipe() __TBB_NOEXCEPT(true) {
+            my_handle = 0;
+#if _WIN32||_WIN64
+            my_thread_id = 0;
+#endif
+        }
+        void internal_move(tbb_thread_v3& x) __TBB_NOEXCEPT(true) {
+            if (joinable()) detach();
+            my_handle = x.my_handle;
+#if _WIN32||_WIN64
+            my_thread_id = x.my_thread_id;
+#endif // _WIN32||_WIN64
+            x.internal_wipe();
+        }
+
         /** Runs start_routine(closure) on another thread and sets my_handle to the handle of the created thread. */
         void __TBB_EXPORTED_METHOD internal_start( __TBB_NATIVE_THREAD_ROUTINE_PTR(start_routine), 
                              void* closure );
         friend void __TBB_EXPORTED_FUNC move_v3( tbb_thread_v3& t1, tbb_thread_v3& t2 );
-        friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 )
+        friend void tbb::swap( tbb_thread_v3& t1, tbb_thread_v3& t2 ) __TBB_NOEXCEPT(true);
     };
         
     class tbb_thread_v3::id { 
 #if _WIN32||_WIN64
-        DWORD my_id;
-        id( DWORD id_ ) : my_id(id_) {}
+        thread_id_type my_id;
+        id( thread_id_type id_ ) : my_id(id_) {}
 #else
         pthread_t my_id;
         id( pthread_t id_ ) : my_id(id_) {}
 #endif // _WIN32||_WIN64
         friend class tbb_thread_v3;
     public:
-        id() : my_id(0) {}
-
-        friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y );
-        friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y );
-        friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y );
-        friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y );
-        friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y );
-        friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y );
+        id() __TBB_NOEXCEPT(true) : my_id(0) {}
+
+        friend bool operator==( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
+        friend bool operator!=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
+        friend bool operator<( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
+        friend bool operator<=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
+        friend bool operator>( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
+        friend bool operator>=( tbb_thread_v3::id x, tbb_thread_v3::id y ) __TBB_NOEXCEPT(true);
         
         template<class charT, class traits>
         friend std::basic_ostream<charT, traits>&
@@ -223,7 +251,7 @@ namespace internal {
         friend tbb_thread_v3::id __TBB_EXPORTED_FUNC thread_get_id_v3();
     }; // tbb_thread_v3::id
 
-    tbb_thread_v3::id tbb_thread_v3::get_id() const {
+    tbb_thread_v3::id tbb_thread_v3::get_id() const __TBB_NOEXCEPT(true) {
 #if _WIN32||_WIN64
         return id(my_thread_id);
 #else
@@ -235,27 +263,27 @@ namespace internal {
     void __TBB_EXPORTED_FUNC thread_yield_v3();
     void __TBB_EXPORTED_FUNC thread_sleep_v3(const tick_count::interval_t &i);
 
-    inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y)
+    inline bool operator==(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
     {
         return x.my_id == y.my_id;
     }
-    inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y)
+    inline bool operator!=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
     {
         return x.my_id != y.my_id;
     }
-    inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y)
+    inline bool operator<(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
     {
         return x.my_id < y.my_id;
     }
-    inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y)
+    inline bool operator<=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
     {
         return x.my_id <= y.my_id;
     }
-    inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y)
+    inline bool operator>(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
     {
         return x.my_id > y.my_id;
     }
-    inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y)
+    inline bool operator>=(tbb_thread_v3::id x, tbb_thread_v3::id y) __TBB_NOEXCEPT(true)
     {
         return x.my_id >= y.my_id;
     }
@@ -276,14 +304,14 @@ inline void move( tbb_thread& t1, tbb_thread& t2 ) {
     internal::move_v3(t1, t2);
 }
 
-inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 ) {
+inline void swap( internal::tbb_thread_v3& t1, internal::tbb_thread_v3& t2 )  __TBB_NOEXCEPT(true) {
     tbb::tbb_thread::native_handle_type h = t1.my_handle;
     t1.my_handle = t2.my_handle;
     t2.my_handle = h;
 #if _WIN32||_WIN64
-    DWORD i = t1.my_thread_id;
-    t1.my_thread_id = t2.my_thread_id;
-    t2.my_thread_id = i;
+    thread_id_type i = t1.my_thread_id;
+    t1.my_thread_id  = t2.my_thread_id;
+    t2.my_thread_id  = i;
 #endif /* _WIN32||_WIN64 */
 }
 
index f0f0ed728fbd74751cc1bda02bd74c6da98c2387..dde395411ed2a89f692786f416ca00a8d0bf5c27 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 /*
index 394afb0a99dbbee8f7d8b79a74ed1cc88500e9cf..b5520f9b049de9f7586dfab64cc37df1ccf8c381 100644 (file)
@@ -1,29 +1,21 @@
 /*
-    Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
-
-    This file is part of Threading Building Blocks.
-
-    Threading Building Blocks is free software; you can redistribute it
-    and/or modify it under the terms of the GNU General Public License
-    version 2 as published by the Free Software Foundation.
-
-    Threading Building Blocks is distributed in the hope that it will be
-    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with Threading Building Blocks; if not, write to the Free Software
-    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
-    As a special exception, you may use this file as part of a free software
-    library without restriction.  Specifically, if other files instantiate
-    templates or use macros or inline functions from this file, or you compile
-    this file and link it with other files to produce an executable, this
-    file does not by itself cause the resulting executable to be covered by
-    the GNU General Public License.  This exception does not however
-    invalidate any other reasons why the executable file might be covered by
-    the GNU General Public License.
+    Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+
+    This file is part of Threading Building Blocks. Threading Building Blocks is free software;
+    you can redistribute it and/or modify it under the terms of the GNU General Public License
+    version 2  as  published  by  the  Free Software Foundation.  Threading Building Blocks is
+    distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
+    implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See  the GNU General Public License for more details.   You should have received a copy of
+    the  GNU General Public License along with Threading Building Blocks; if not, write to the
+    Free Software Foundation, Inc.,  51 Franklin St,  Fifth Floor,  Boston,  MA 02110-1301 USA
+
+    As a special exception,  you may use this file  as part of a free software library without
+    restriction.  Specifically,  if other files instantiate templates  or use macros or inline
+    functions from this file, or you compile this file and link it with other files to produce
+    an executable,  this file does not by itself cause the resulting executable to be covered
+    by the GNU General Public License. This exception does not however invalidate any other
+    reasons why the executable file might be covered by the GNU General Public License.
 */
 
 #ifndef __TBB_tick_count_H
@@ -79,6 +71,19 @@ public:
 
         //! Subtraction operator
         interval_t& operator-=( const interval_t& i ) {value -= i.value; return *this;}
+    private:
+        static long long ticks_per_second(){
+#if _WIN32||_WIN64
+            LARGE_INTEGER qpfreq;
+            int rval = QueryPerformanceFrequency(&qpfreq);
+            __TBB_ASSERT_EX(rval, "QueryPerformanceFrequency returned zero");
+            return static_cast<long long>(qpfreq.QuadPart);
+#elif __linux__
+            return static_cast<long long>(1E9);
+#else /* generic Unix */
+            return static_cast<long long>(1E6);
+#endif /* (choice of OS) */
+        }
     };
     
     //! Construct an absolute timestamp initialized to zero.
@@ -90,6 +95,9 @@ public:
     //! Subtract two timestamps to get the time interval between
     friend interval_t operator-( const tick_count& t1, const tick_count& t0 );
 
+    //! Return the resolution of the clock in seconds per tick.
+    static double resolution() { return 1.0 / interval_t::ticks_per_second(); }
+
 private:
     long long my_count;
 };
@@ -98,39 +106,25 @@ inline tick_count tick_count::now() {
     tick_count result;
 #if _WIN32||_WIN64
     LARGE_INTEGER qpcnt;
-    QueryPerformanceCounter(&qpcnt);
+    int rval = QueryPerformanceCounter(&qpcnt);
+    __TBB_ASSERT_EX(rval, "QueryPerformanceCounter failed");
     result.my_count = qpcnt.QuadPart;
 #elif __linux__
     struct timespec ts;
-#if TBB_USE_ASSERT
-    int status = 
-#endif /* TBB_USE_ASSERT */
-        clock_gettime( CLOCK_REALTIME, &ts );
-    __TBB_ASSERT( status==0, "CLOCK_REALTIME not supported" );
+    int status = clock_gettime( CLOCK_REALTIME, &ts );
+    __TBB_ASSERT_EX( status==0, "CLOCK_REALTIME not supported" );
     result.my_count = static_cast<long long>(1000000000UL)*static_cast<long long>(ts.tv_sec) + static_cast<long long>(ts.tv_nsec);
 #else /* generic Unix */
     struct timeval tv;
-#if TBB_USE_ASSERT
-    int status = 
-#endif /* TBB_USE_ASSERT */
-        gettimeofday(&tv, NULL);
-    __TBB_ASSERT( status==0, "gettimeofday failed" );
+    int status = gettimeofday(&tv, NULL);
+    __TBB_ASSERT_EX( status==0, "gettimeofday failed" );
     result.my_count = static_cast<long long>(1000000)*static_cast<long long>(tv.tv_sec) + static_cast<long long>(tv.tv_usec);
 #endif /*(choice of OS) */
     return result;
 }
 
-inline tick_count::interval_t::interval_t( double sec )
-{
-#if _WIN32||_WIN64
-    LARGE_INTEGER qpfreq;
-    QueryPerformanceFrequency(&qpfreq);
-    value = static_cast<long long>(sec*qpfreq.QuadPart);
-#elif __linux__
-    value = static_cast<long long>(sec*1E9);
-#else /* generic Unix */
-    value = static_cast<long long>(sec*1E6);
-#endif /* (choice of OS) */
+inline tick_count::interval_t::interval_t( double sec ) {
+    value = static_cast<long long>(sec*interval_t::ticks_per_second());
 }
 
 inline tick_count::interval_t operator-( const tick_count& t1, const tick_count& t0 ) {
@@ -138,18 +132,9 @@ inline tick_count::interval_t operator-( const tick_count& t1, const tick_count&
 }
 
 inline double tick_count::interval_t::seconds() const {
-#if _WIN32||_WIN64
-    LARGE_INTEGER qpfreq;
-    QueryPerformanceFrequency(&qpfreq);
-    return value/(double)qpfreq.QuadPart;
-#elif __linux__
-    return value*1E-9;
-#else /* generic Unix */
-    return value*1E-6;
-#endif /* (choice of OS) */
+    return value*tick_count::resolution();
 }
 
 } // namespace tbb
 
 #endif /* __TBB_tick_count_H */
-
index a11de1d61ee1a018540568470eaf8596df3c2c10..304a5f6cbaf96bdc66316049efb63f0e18d88133 100644 (file)
Binary files a/dependencies64/tbb/lib/irml/irml.lib and b/dependencies64/tbb/lib/irml/irml.lib differ
index b729189991a83ce444814902c97d3ed5c3a528d2..c6519fb258246dcfd7568e8d402c07c120c130f5 100644 (file)
Binary files a/dependencies64/tbb/lib/irml/irml_debug.lib and b/dependencies64/tbb/lib/irml/irml_debug.lib differ
diff --git a/dependencies64/tbb/lib/irml_c/irml.lib b/dependencies64/tbb/lib/irml_c/irml.lib
deleted file mode 100644 (file)
index 1442f63..0000000
Binary files a/dependencies64/tbb/lib/irml_c/irml.lib and /dev/null differ
diff --git a/dependencies64/tbb/lib/irml_c/irml_debug.lib b/dependencies64/tbb/lib/irml_c/irml_debug.lib
deleted file mode 100644 (file)
index 12ddcd8..0000000
Binary files a/dependencies64/tbb/lib/irml_c/irml_debug.lib and /dev/null differ
index 41a4f456544e1ae9504e9984c17c0340a766280d..a8eb7ebbabb1a4148297cf1845ea1d8b062696ad 100644 (file)
@@ -1,5 +1,4 @@
-
-; Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
+; Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
 ;
 ; The source code contained or described herein and all documents related
 ; to the source code ("Material") are owned by Intel Corporation or its
 ; implication, inducement, estoppel or otherwise.  Any license under such
 ; intellectual property rights must be express and approved by Intel in
 ; writing.
-;
+
 ; This file is organized with a section for each .cpp file.
 ; Each of these sections is in alphabetical order.
 
 EXPORTS
 
+; Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
+;
+; The source code contained or described herein and all documents related
+; to the source code ("Material") are owned by Intel Corporation or its
+; suppliers or licensors.  Title to the Material remains with Intel
+; Corporation or its suppliers and licensors.  The Material is protected
+; by worldwide copyright laws and treaty provisions.  No part of the
+; Material may be used, copied, reproduced, modified, published, uploaded,
+; posted, transmitted, distributed, or disclosed in any way without
+; Intel's prior express written permission.
+;
+; No license under any patent, copyright, trade secret or other
+; intellectual property right is granted to or conferred upon you by
+; disclosure or delivery of the Materials, either expressly, by
+; implication, inducement, estoppel or otherwise.  Any license under such
+; intellectual property rights must be express and approved by Intel in
+; writing.
 
 
 
@@ -44,6 +60,7 @@ EXPORTS
 
 
 
 
 
 
@@ -52,15 +69,20 @@ EXPORTS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -73,143 +95,23 @@ EXPORTS
 
 
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    
-
-
-
-    
-    
-
-
-        
     
 
 
-
     
         
     
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-    
-
-
-
-
-
-
-
-
-
-
-    
-
-
-
     
-
-
-
-
-
-
-
     
 
-
-
+     
+         
     
+     
 
 
 
@@ -217,10 +119,6 @@ EXPORTS
 
 
 
-    
-
-
-
 
 
 
@@ -229,23 +127,36 @@ EXPORTS
 
 
 
+     
 
+     
 
 
 
 
 
 
 
 
+     
 
+     
 
 
 
 
 
 
 
 
 
 
@@ -262,16 +173,19 @@ EXPORTS
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
@@ -290,6 +204,7 @@ EXPORTS
 
 
 
 
 
 
@@ -297,9 +212,8 @@ EXPORTS
 
 
 
-    
 
-    
 
 
 
@@ -313,6 +227,9 @@ __TBB_machine_cmpswp2
 __TBB_machine_fetchadd2
 __TBB_machine_fetchstore2
 __TBB_machine_pause
+__TBB_machine_try_lock_elided
+__TBB_machine_unlock_elided
+__TBB_machine_is_in_transaction
 
 
 ?NFS_Allocate@internal@tbb@@YAPEAX_K0PEAX@Z
@@ -346,26 +263,30 @@ __TBB_machine_pause
 ?terminate@task_scheduler_init@tbb@@QEAAXXZ
 ?observe@task_scheduler_observer_v3@internal@tbb@@QEAAX_N@Z
 
+?internal_current_slot@task_arena_base@internal@interface7@tbb@@KAHXZ
+?internal_initialize@task_arena_base@internal@interface7@tbb@@IEAAXXZ
+?internal_terminate@task_arena_base@internal@interface7@tbb@@IEAAXXZ
+?internal_enqueue@task_arena_base@internal@interface7@tbb@@IEBAXAEAVtask@4@_J@Z
+?internal_execute@task_arena_base@internal@interface7@tbb@@IEBAXAEAVdelegate_base@234@@Z
+?internal_wait@task_arena_base@internal@interface7@tbb@@IEBAXXZ
 
 
 ?destroy@task@tbb@@QEAAXAEAV12@@Z
 
 
-
-
 ?allocate@allocate_root_with_context_proxy@internal@tbb@@QEBAAEAVtask@3@_K@Z
 ?free@allocate_root_with_context_proxy@internal@tbb@@QEBAXAEAVtask@3@@Z
 ?change_group@task@tbb@@QEAAXAEAVtask_group_context@2@@Z
 ?is_group_execution_cancelled@task_group_context@tbb@@QEBA_NXZ
 ?cancel_group_execution@task_group_context@tbb@@QEAA_NXZ
 ?reset@task_group_context@tbb@@QEAAXXZ
+?capture_fp_settings@task_group_context@tbb@@QEAAXXZ
 ?init@task_group_context@tbb@@IEAAXXZ
 ?register_pending_exception@task_group_context@tbb@@QEAAXXZ
 ??1task_group_context@tbb@@QEAA@XZ
-
 ?set_priority@task_group_context@tbb@@QEAAXW4priority_t@2@@Z
 ?priority@task_group_context@tbb@@QEBA?AW4priority_t@2@XZ
-
 ?name@captured_exception@tbb@@UEBAPEBDXZ
 ?what@captured_exception@tbb@@UEBAPEBDXZ
 ??1captured_exception@tbb@@UEAA@XZ
@@ -375,13 +296,13 @@ __TBB_machine_pause
 ?clear@captured_exception@tbb@@QEAAXXZ
 
 
-
 ?throw_bad_last_alloc_exception_v4@internal@tbb@@YAXXZ
 ?throw_exception_v4@internal@tbb@@YAXW4exception_id@12@@Z
 ?what@bad_last_alloc@tbb@@UEBAPEBDXZ
 ?what@missing_wait@tbb@@UEBAPEBDXZ
 ?what@invalid_multiple_scheduling@tbb@@UEBAPEBDXZ
 ?what@improper_lock@tbb@@UEBAPEBDXZ
+?what@user_abort@tbb@@UEBAPEBDXZ
 
 
 ?assertion_failure@tbb@@YAXPEBDH00@Z
@@ -407,9 +328,7 @@ TBB_runtime_interface_version
 ?clear@pipeline@tbb@@QEAAXXZ
 ?inject_token@pipeline@tbb@@AEAAXAEAVtask@2@@Z
 ?run@pipeline@tbb@@QEAAX_K@Z
-
 ?run@pipeline@tbb@@QEAAX_KAEAVtask_group_context@2@@Z
-
 ?process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ
 ?try_process_item@thread_bound_filter@tbb@@QEAA?AW4result_type@12@XZ
 ?set_end_of_input@filter@tbb@@IEAAXXZ
@@ -436,7 +355,6 @@ TBB_runtime_interface_version
 ?internal_destroy@scoped_lock_read@reader_writer_lock@interface5@tbb@@AEAAXXZ
 
 
-
 ?internal_itt_releasing@spin_rw_mutex@tbb@@CAXPEAV12@@Z
 ?internal_acquire_writer@spin_rw_mutex@tbb@@CA_NPEAV12@@Z
 ?internal_acquire_reader@spin_rw_mutex@tbb@@CAXPEAV12@@Z
@@ -448,7 +366,6 @@ TBB_runtime_interface_version
 ?internal_try_acquire_reader@spin_rw_mutex@tbb@@CA_NPEAV12@@Z
 
 
-
 ?internal_construct@spin_rw_mutex_v3@tbb@@AEAAXXZ
 ?internal_upgrade@spin_rw_mutex_v3@tbb@@AEAA_NXZ
 ?internal_downgrade@spin_rw_mutex_v3@tbb@@AEAAXXZ
@@ -460,6 +377,15 @@ TBB_runtime_interface_version
 ?internal_try_acquire_writer@spin_rw_mutex_v3@tbb@@AEAA_NXZ
 
 
+?internal_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z
+?internal_acquire_reader@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@_N@Z
+?internal_upgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z
+?internal_downgrade@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z
+?internal_try_acquire_writer@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAA_NAEAVscoped_lock@1234@@Z
+?internal_release@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXAEAVscoped_lock@1234@@Z
+?internal_construct@x86_rtm_rw_mutex@internal@interface8@tbb@@AEAAXXZ
+
+
 ?internal_construct@spin_mutex@tbb@@QEAAXXZ
 ?internal_acquire@scoped_lock@spin_mutex@tbb@@AEAAXAEAV23@@Z
 ?internal_release@scoped_lock@spin_mutex@tbb@@AEAAXXZ
@@ -489,7 +415,6 @@ TBB_runtime_interface_version
 ?internal_construct@critical_section_v4@internal@tbb@@QEAAXXZ
 
 
-
 ?internal_grow_predicate@hash_map_segment_base@internal@tbb@@QEBA_NXZ
 
 
@@ -507,7 +432,6 @@ TBB_runtime_interface_version
 ?internal_size@concurrent_queue_base@internal@tbb@@IEBA_JXZ
 
 
-
 ??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@@Z
 ??0concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@AEBVconcurrent_queue_base_v3@12@_K@Z
 ??1concurrent_queue_iterator_base_v3@internal@tbb@@IEAA@XZ
@@ -516,16 +440,19 @@ TBB_runtime_interface_version
 ??0concurrent_queue_base_v3@internal@tbb@@IEAA@_K@Z
 ??1concurrent_queue_base_v3@internal@tbb@@MEAA@XZ
 ?internal_push@concurrent_queue_base_v3@internal@tbb@@IEAAXPEBX@Z
+?internal_push_move@concurrent_queue_base_v8@internal@tbb@@IEAAXPEBX@Z
 ?internal_push_if_not_full@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEBX@Z
+?internal_push_move_if_not_full@concurrent_queue_base_v8@internal@tbb@@IEAA_NPEBX@Z
 ?internal_pop@concurrent_queue_base_v3@internal@tbb@@IEAAXPEAX@Z
 ?internal_pop_if_present@concurrent_queue_base_v3@internal@tbb@@IEAA_NPEAX@Z
+?internal_abort@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ
 ?internal_size@concurrent_queue_base_v3@internal@tbb@@IEBA_JXZ
 ?internal_empty@concurrent_queue_base_v3@internal@tbb@@IEBA_NXZ
 ?internal_finish_clear@concurrent_queue_base_v3@internal@tbb@@IEAAXXZ
 ?internal_set_capacity@concurrent_queue_base_v3@internal@tbb@@IEAAX_J_K@Z
 ?internal_throw_exception@concurrent_queue_base_v3@internal@tbb@@IEBAXXZ
 ?assign@concurrent_queue_base_v3@internal@tbb@@IEAAXAEBV123@@Z
-
+?move_content@concurrent_queue_base_v8@internal@tbb@@IEAAXAEAV123@@Z
 
 
 ?internal_assign@concurrent_vector_base@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z
@@ -538,7 +465,6 @@ TBB_runtime_interface_version
 ?internal_reserve@concurrent_vector_base@internal@tbb@@IEAAX_K00@Z
 
 
-
 ??1concurrent_vector_base_v3@internal@tbb@@IEAA@XZ
 ?internal_assign@concurrent_vector_base_v3@internal@tbb@@IEAAXAEBV123@_KP6AXPEAX1@ZP6AX2PEBX1@Z5@Z
 ?internal_capacity@concurrent_vector_base_v3@internal@tbb@@IEBA_KXZ
@@ -574,5 +500,3 @@ TBB_runtime_interface_version
 ?internal_destroy_condition_variable@internal@interface5@tbb@@YAXAEATcondvar_impl_t@123@@Z
 
 
-
-
index 4e4333b1c889376252cdd894baa06747efddf025..c16727a4974fc602993f36333715b244eac07929 100644 (file)
Binary files a/dependencies64/tbb/lib/tbb.lib and b/dependencies64/tbb/lib/tbb.lib differ
index 0ab621b2768f5247b1bf55118b8f68f574109359..f974a75772708334f4c56d8d0feca62f88abf9f4 100644 (file)
Binary files a/dependencies64/tbb/lib/tbb_debug.lib and b/dependencies64/tbb/lib/tbb_debug.lib differ
index 515f064a0f7cc47a311eca7e15ab4f3a92804fe3..bdceb7c7b031cd41220e2b949bb03f24960d41d1 100644 (file)
Binary files a/dependencies64/tbb/lib/tbb_preview.lib and b/dependencies64/tbb/lib/tbb_preview.lib differ
index 69d066356524771ed79da18b918f6f0e4c96617e..e6ecf5f9ae8772dbc527330efc23516c0fa735b0 100644 (file)
Binary files a/dependencies64/tbb/lib/tbb_preview_debug.lib and b/dependencies64/tbb/lib/tbb_preview_debug.lib differ
index 104f5f7d8588f677ad92d6545004404f84a91127..8f22c913142466887e19acded50c5c1c538eb305 100644 (file)
@@ -1,5 +1,4 @@
-
-; Copyright 2005-2011 Intel Corporation.  All Rights Reserved.
+; Copyright 2005-2014 Intel Corporation.  All Rights Reserved.
 ;
 ; The source code contained or described herein and all documents related
 ; to the source code ("Material") are owned by Intel Corporation or its
@@ -28,15 +27,21 @@ scalable_posix_memalign
 scalable_aligned_malloc
 scalable_aligned_realloc
 scalable_aligned_free
-safer_scalable_free
-safer_scalable_realloc
 scalable_msize
-safer_scalable_msize
-safer_scalable_aligned_realloc
+scalable_allocation_mode
+scalable_allocation_command
+__TBB_malloc_safer_free
+__TBB_malloc_safer_realloc
+__TBB_malloc_safer_msize
+__TBB_malloc_safer_aligned_msize
+__TBB_malloc_safer_aligned_realloc
 ; memory pool stuff
 ?pool_create@rml@@YAPEAVMemoryPool@1@_JPEBUMemPoolPolicy@1@@Z
+?pool_create_v1@rml@@YA?AW4MemPoolError@1@_JPEBUMemPoolPolicy@1@PEAPEAVMemoryPool@1@@Z
 ?pool_destroy@rml@@YA_NPEAVMemoryPool@1@@Z
 ?pool_malloc@rml@@YAPEAXPEAVMemoryPool@1@_K@Z
 ?pool_free@rml@@YA_NPEAVMemoryPool@1@PEAX@Z
 ?pool_reset@rml@@YA_NPEAVMemoryPool@1@@Z
 ?pool_realloc@rml@@YAPEAXPEAVMemoryPool@1@PEAX_K@Z
+?pool_aligned_realloc@rml@@YAPEAXPEAVMemoryPool@1@PEAX_K2@Z
+?pool_aligned_malloc@rml@@YAPEAXPEAVMemoryPool@1@_K1@Z
index 3f39af140005a505389db29483737e69c2f6fc1d..cdab1e3ada51b21424813126eeca18ab8fae352e 100644 (file)
Binary files a/dependencies64/tbb/lib/tbbmalloc.lib and b/dependencies64/tbb/lib/tbbmalloc.lib differ
index 97243d0de85ff4ba0bd21f8b5ec8323d238697dd..2efec83119c8fccbc0f7a234340ab5202888008b 100644 (file)
Binary files a/dependencies64/tbb/lib/tbbmalloc_debug.lib and b/dependencies64/tbb/lib/tbbmalloc_debug.lib differ
index d84b99fc51407b9d5a998be3de84b437eb3cc36a..7385c8732ec37fa382a53448fcc2a2240f134e2b 100644 (file)
Binary files a/dependencies64/tbb/lib/tbbmalloc_proxy.lib and b/dependencies64/tbb/lib/tbbmalloc_proxy.lib differ
index 1de9d2679fcd189670f6493d16cbd855912b859e..15bcdb6728b1fc5ca6b0104843f5216a74025e27 100644 (file)
Binary files a/dependencies64/tbb/lib/tbbmalloc_proxy_debug.lib and b/dependencies64/tbb/lib/tbbmalloc_proxy_debug.lib differ
index e860750bcc7feb242bdfd62fff7891024d03f78f..2b18a01977276705ea8eb5d7783eaf95f1375442 100644 (file)
Binary files a/dependencies64/tbb/lib/tbbproxy.lib and b/dependencies64/tbb/lib/tbbproxy.lib differ
diff --git a/dependencies64/tbb/lib/tbbproxy.pdb b/dependencies64/tbb/lib/tbbproxy.pdb
new file mode 100644 (file)
index 0000000..07a1de7
Binary files /dev/null and b/dependencies64/tbb/lib/tbbproxy.pdb differ
index d222941c6a38a8b6fb0be823a0da9ac2ed9a0082..7122c258d52e10743d5401ed14d62ad2d2948c39 100644 (file)
Binary files a/dependencies64/tbb/lib/tbbproxy_debug.lib and b/dependencies64/tbb/lib/tbbproxy_debug.lib differ
diff --git a/dependencies64/tbb/lib/tbbproxy_debug.pdb b/dependencies64/tbb/lib/tbbproxy_debug.pdb
new file mode 100644 (file)
index 0000000..022095c
Binary files /dev/null and b/dependencies64/tbb/lib/tbbproxy_debug.pdb differ
diff --git a/dependencies64/zlib/lib/zlibstat.lib b/dependencies64/zlib/lib/zlibstat.lib
new file mode 100644 (file)
index 0000000..adeac2c
Binary files /dev/null and b/dependencies64/zlib/lib/zlibstat.lib differ