diff --git a/README.md b/README.md index d11adf35..5ea5e027 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ The entire queue's implementation is contained in **one header**, [`concurrentqu Simply download and include that to use the queue. The blocking version is in a separate header, [`blockingconcurrentqueue.h`][blockingconcurrentqueue.h], that depends on the first. The implementation makes use of certain key C++11 features, so it requires a fairly recent compiler -(e.g. VS2013+ or g++ 4.8; note that g++ 4.6 has a known bug with `std::atomic` and is thus not supported). +(e.g. VS2012+ or g++ 4.8; note that g++ 4.6 has a known bug with `std::atomic` and is thus not supported). The algorithm implementations themselves are platform independent. Use it like you would any other templated queue, with the exception that you can use diff --git a/blockingconcurrentqueue.h b/blockingconcurrentqueue.h index d00dc745..c114864a 100644 --- a/blockingconcurrentqueue.h +++ b/blockingconcurrentqueue.h @@ -62,8 +62,8 @@ namespace details private: void* m_hSema; - Semaphore(const Semaphore& other) = delete; - Semaphore& operator=(const Semaphore& other) = delete; + Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; + Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; public: Semaphore(int initialCount = 0) @@ -99,8 +99,8 @@ namespace details private: semaphore_t m_sema; - Semaphore(const Semaphore& other) = delete; - Semaphore& operator=(const Semaphore& other) = delete; + Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; + Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; public: Semaphore(int initialCount = 0) @@ -141,8 +141,8 @@ namespace details private: sem_t m_sema; - Semaphore(const Semaphore& other) = delete; - Semaphore& operator=(const Semaphore& other) = delete; + Semaphore(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; + Semaphore& operator=(const Semaphore& other) MOODYCAMEL_DELETE_FUNCTION; public: Semaphore(int initialCount = 0) @@ -365,8 +365,8 @@ class BlockingConcurrentQueue } // Disable copying and copy assignment - BlockingConcurrentQueue(BlockingConcurrentQueue const&) = delete; - BlockingConcurrentQueue& operator=(BlockingConcurrentQueue const&) = delete; + BlockingConcurrentQueue(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; + BlockingConcurrentQueue& operator=(BlockingConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; // Moving is supported, but note that it is *not* a thread-safe operation. // Nobody can use the queue while it's being moved, and the memory effects diff --git a/concurrentqueue.h b/concurrentqueue.h index 28dde50c..61c87133 100644 --- a/concurrentqueue.h +++ b/concurrentqueue.h @@ -148,6 +148,14 @@ namespace moodycamel { namespace details { #endif #endif +// VS2012 doesn't support deleted functions. +// In this case, we declare the function normally but don't define it. A link error will be generated if the function is called. +#if defined(_MSC_VER) && _MSC_VER <= 1700 +#define MOODYCAMEL_DELETE_FUNCTION +#else +#define MOODYCAMEL_DELETE_FUNCTION =delete +#endif + // Compiler-specific likely/unlikely hints namespace moodycamel { namespace details { #if defined(__GNUC__) @@ -437,8 +445,8 @@ namespace details private: ThreadExitNotifier() : tail(nullptr) { } - ThreadExitNotifier(ThreadExitNotifier const&) = delete; - ThreadExitNotifier& operator=(ThreadExitNotifier const&) = delete; + ThreadExitNotifier(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; + ThreadExitNotifier& operator=(ThreadExitNotifier const&) MOODYCAMEL_DELETE_FUNCTION; ~ThreadExitNotifier() { @@ -527,8 +535,8 @@ struct ProducerToken } // Disable copying and assignment - ProducerToken(ProducerToken const&) = delete; - ProducerToken& operator=(ProducerToken const&) = delete; + ProducerToken(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; + ProducerToken& operator=(ProducerToken const&) MOODYCAMEL_DELETE_FUNCTION; private: template friend class ConcurrentQueue; @@ -568,8 +576,8 @@ struct ConsumerToken } // Disable copying and assignment - ConsumerToken(ConsumerToken const&) = delete; - ConsumerToken& operator=(ConsumerToken const&) = delete; + ConsumerToken(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; + ConsumerToken& operator=(ConsumerToken const&) MOODYCAMEL_DELETE_FUNCTION; private: template friend class ConcurrentQueue; @@ -725,8 +733,8 @@ class ConcurrentQueue } // Disable copying and copy assignment - ConcurrentQueue(ConcurrentQueue const&) = delete; - ConcurrentQueue& operator=(ConcurrentQueue const&) = delete; + ConcurrentQueue(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; + ConcurrentQueue& operator=(ConcurrentQueue const&) MOODYCAMEL_DELETE_FUNCTION; // Moving is supported, but note that it is *not* a thread-safe operation. // Nobody can use the queue while it's being moved, and the memory effects @@ -1276,8 +1284,8 @@ class ConcurrentQueue FreeList(FreeList&& other) : freeListHead(other.freeListHead.load(std::memory_order_relaxed)) { other.freeListHead.store(nullptr, std::memory_order_relaxed); } void swap(FreeList& other) { details::swap_relaxed(freeListHead, other.freeListHead); } - FreeList(FreeList const&) = delete; - FreeList& operator=(FreeList const&) = delete; + FreeList(FreeList const&) MOODYCAMEL_DELETE_FUNCTION; + FreeList& operator=(FreeList const&) MOODYCAMEL_DELETE_FUNCTION; inline void add(N* node) {