/*
 * Author: Chris Caron <lead2gold@gmail.com>
 * Date: Tue, Aug 2nd, 2016
 * URL: http://nuxref.com
 * This check allows NZBGet v17 to be compiled using a C++11
 * compiler
 */
diff -Naur nzbget-17.0/config.h.in nzbget-17.0.patched/config.h.in
--- nzbget-17.0/config.h.in	2016-07-27 09:46:21.000000000 -0400
+++ nzbget-17.0.patched/config.h.in	2016-08-02 15:58:05.907166847 -0400
@@ -38,8 +38,8 @@
 /* Define to 1 if you have the <curses.h> header file. */
 #undef HAVE_CURSES_H
 
-/* define if the compiler supports basic C++14 syntax */
-#undef HAVE_CXX14
+/* define if the compiler supports basic C++11 syntax */
+#undef HAVE_CXX11
 
 /* Define to 1 if you have the <endian.h> header file. */
 #undef HAVE_ENDIAN_H
diff -Naur nzbget-17.0/configure.ac nzbget-17.0.patched/configure.ac
--- nzbget-17.0/configure.ac	2016-07-27 09:46:01.000000000 -0400
+++ nzbget-17.0.patched/configure.ac	2016-08-02 13:41:34.051616766 -0400
@@ -47,18 +47,18 @@
 AC_LANG(C++)
 
 dnl
-dnl Determine compiler switches to support C++14 standard.
+dnl Determine compiler switches to support C++11 standard.
 dnl
 AC_MSG_CHECKING(whether to test compiler features)
 AC_ARG_ENABLE(cpp-check,
-	[AS_HELP_STRING([--disable-cpp-check], [disable check for C++14 compiler features])],
+	[AS_HELP_STRING([--disable-cpp-check], [disable check for C++11 compiler features])],
 	[ ENABLECPPCHECK=$enableval ],
 	[ ENABLECPPCHECK=yes] )
 AC_MSG_RESULT($ENABLECPPCHECK)
 if test "$ENABLECPPCHECK" = "yes"; then
-	AX_CXX_COMPILE_STDCXX(14,,[optional])
-	if test "$HAVE_CXX14" != "1"; then
-		AC_MSG_ERROR("A compiler with support for C++14 language features is required. For details visit http://nzbget.net/cpp14")
+	AX_CXX_COMPILE_STDCXX(11,,[optional])
+	if test "$HAVE_CXX11" != "1"; then
+		AC_MSG_ERROR("A compiler with support for C++11 language features is required.")
 	fi
 fi
 
diff -Naur nzbget-17.0/daemon/connect/Connection.cpp nzbget-17.0.patched/daemon/connect/Connection.cpp
--- nzbget-17.0/daemon/connect/Connection.cpp	2016-07-27 09:46:01.000000000 -0400
+++ nzbget-17.0.patched/daemon/connect/Connection.cpp	2016-08-02 15:23:16.765454619 -0400
@@ -21,6 +21,7 @@
 
 #include "nzbget.h"
 #include "Connection.h"
+#include "Util.h"
 #include "Log.h"
 
 static const int CONNECTION_READBUFFER_SIZE = 1024;
diff -Naur nzbget-17.0/daemon/connect/TlsSocket.cpp nzbget-17.0.patched/daemon/connect/TlsSocket.cpp
--- nzbget-17.0/daemon/connect/TlsSocket.cpp	2016-07-27 09:46:02.000000000 -0400
+++ nzbget-17.0.patched/daemon/connect/TlsSocket.cpp	2016-08-02 15:23:24.750202743 -0400
@@ -24,6 +24,7 @@
 
 #include "TlsSocket.h"
 #include "Thread.h"
+#include "Util.h"
 #include "Log.h"
 
 class TlsSocketFinalizer
diff -Naur nzbget-17.0/daemon/main/Scheduler.cpp nzbget-17.0.patched/daemon/main/Scheduler.cpp
--- nzbget-17.0/daemon/main/Scheduler.cpp	2016-07-27 09:46:03.000000000 -0400
+++ nzbget-17.0.patched/daemon/main/Scheduler.cpp	2016-08-02 15:54:37.067284550 -0400
@@ -21,6 +21,7 @@
 #include "nzbget.h"
 #include "Scheduler.h"
 #include "Options.h"
+#include "Util.h"
 #include "Log.h"
 #include "NewsServer.h"
 #include "ServerPool.h"
@@ -40,7 +41,7 @@
 		Guard guard(m_taskListMutex);
 
 		std::sort(m_taskList.begin(), m_taskList.end(),
-			[](std::unique_ptr<Task>& task1, std::unique_ptr<Task>& task2)
+			[](const std::unique_ptr<Scheduler::Task>& task1, const std::unique_ptr<Scheduler::Task>& task2)
 		{
 			return (task1->m_hours < task2->m_hours) ||
 				((task1->m_hours == task2->m_hours) && (task1->m_minutes < task2->m_minutes));
diff -Naur nzbget-17.0/daemon/queue/QueueEditor.cpp nzbget-17.0.patched/daemon/queue/QueueEditor.cpp
--- nzbget-17.0/daemon/queue/QueueEditor.cpp	2016-07-27 09:46:03.000000000 -0400
+++ nzbget-17.0.patched/daemon/queue/QueueEditor.cpp	2016-08-02 15:55:01.432570402 -0400
@@ -38,7 +38,7 @@
 	GroupSorter(NzbList* nzbList, QueueEditor::ItemList* sortItemList) :
 		m_nzbList(nzbList), m_sortItemList(sortItemList) {}
 	bool Execute(const char* sort);
-	bool operator()(std::unique_ptr<NzbInfo>& refNzbInfo1, std::unique_ptr<NzbInfo>& refNzbInfo2) const;
+	bool operator()(const std::unique_ptr<NzbInfo>& refNzbInfo1, const std::unique_ptr<NzbInfo>& refNzbInfo2) const;
 
 private:
 	enum ESortCriteria
@@ -129,8 +129,8 @@
 	std::sort(m_nzbList->begin(), m_nzbList->end(), *this);
 
 	if (origSortOrder == soAuto &&
-		std::equal(tempList.begin(), tempList.end(), m_nzbList->begin(), m_nzbList->end(),
-		[](NzbInfo* nzbInfo1, std::unique_ptr<NzbInfo>& nzbInfo2)
+		std::equal(tempList.begin(), tempList.end(), m_nzbList->begin(),
+		[](NzbInfo* nzbInfo1, std::unique_ptr<NzbInfo>& nzbInfo2) -> bool
 		{
 			return nzbInfo1 == nzbInfo2.get();
 		}))
@@ -142,7 +142,7 @@
 	return true;
 }
 
-bool GroupSorter::operator()(std::unique_ptr<NzbInfo>& refNzbInfo1, std::unique_ptr<NzbInfo>& refNzbInfo2) const
+bool GroupSorter::operator()(const std::unique_ptr<NzbInfo>& refNzbInfo1, const std::unique_ptr<NzbInfo>& refNzbInfo2) const
 {
 	NzbInfo* nzbInfo1 = refNzbInfo1.get();
 	NzbInfo* nzbInfo2 = refNzbInfo2.get();
diff -Naur nzbget-17.0/daemon/util/Observer.h nzbget-17.0.patched/daemon/util/Observer.h
--- nzbget-17.0/daemon/util/Observer.h	2016-07-27 09:46:04.000000000 -0400
+++ nzbget-17.0.patched/daemon/util/Observer.h	2016-08-02 15:23:43.527611072 -0400
@@ -27,6 +27,10 @@
 class Subject
 {
 public:
+    	typedef typename std::vector<Observer*>::iterator iterator;
+   	typedef typename std::vector<Observer*>::const_iterator const_iterator;
+
+
 	void Attach(Observer* observer);
 	void Detach(Observer* observer);
 	void Notify(void* aspect);
diff -Naur nzbget-17.0/daemon/util/Thread.cpp nzbget-17.0.patched/daemon/util/Thread.cpp
--- nzbget-17.0/daemon/util/Thread.cpp	2016-07-27 09:46:04.000000000 -0400
+++ nzbget-17.0.patched/daemon/util/Thread.cpp	2016-08-02 15:57:06.725899703 -0400
@@ -20,6 +20,7 @@
 
 #include "nzbget.h"
 #include "Log.h"
+#include "Util.h"
 #include "Thread.h"
 
 int Thread::m_threadCount = 1; // take the main program thread into account
diff -Naur nzbget-17.0/daemon/util/Thread.h nzbget-17.0.patched/daemon/util/Thread.h
--- nzbget-17.0/daemon/util/Thread.h	2016-07-27 09:46:04.000000000 -0400
+++ nzbget-17.0.patched/daemon/util/Thread.h	2016-08-02 15:23:55.002249953 -0400
@@ -69,9 +69,17 @@
 	T* operator->() { return m_ptr; }
 	operator T*() { return m_ptr; }
 
+    	typedef typename T::iterator iterator;
+   	typedef typename T::const_iterator const_iterator;
+
 	// for-range loops on GuardedPtr
-	auto begin() { return m_ptr->begin(); }
-	auto end() { return m_ptr->end(); }
+    	iterator begin() {return m_ptr->begin();}
+    	const_iterator begin() const {return m_ptr->begin();}
+    	const_iterator cbegin() const {return m_ptr->cbegin();}
+    	iterator end() {return m_ptr->end();}
+    	const_iterator end() const {return m_ptr->end();}
+    	const_iterator cend() const {return m_ptr->cend();}
+
 
 private:
 	T* m_ptr;
diff -Naur nzbget-17.0/daemon/util/Util.h nzbget-17.0.patched/daemon/util/Util.h
--- nzbget-17.0/daemon/util/Util.h	2016-07-27 09:46:04.000000000 -0400
+++ nzbget-17.0.patched/daemon/util/Util.h	2016-08-02 15:24:09.279801077 -0400
@@ -21,6 +21,11 @@
 #ifndef UTIL_H
 #define UTIL_H
 
+#include <cstddef>
+#include <memory>
+#include <type_traits>
+#include <utility>
+
 #include "NString.h"
 
 #ifdef WIN32
@@ -314,4 +319,37 @@
 	bool m_working = false;
 };
 
+// Ref: C++11 Backwards Compatibility for make_unique()
+// http://stackoverflow.com/questions/17902405/\
+//    how-to-implement-make-unique-function-in-c11/17902439#17902439
+namespace std {
+    template<class T> struct _Unique_if {
+        typedef unique_ptr<T> _Single_object;
+    };
+
+    template<class T> struct _Unique_if<T[]> {
+        typedef unique_ptr<T[]> _Unknown_bound;
+    };
+
+    template<class T, size_t N> struct _Unique_if<T[N]> {
+        typedef void _Known_bound;
+    };
+
+    template<class T, class... Args>
+        typename _Unique_if<T>::_Single_object
+        make_unique(Args&&... args) {
+            return unique_ptr<T>(new T(std::forward<Args>(args)...));
+        }
+
+    template<class T>
+        typename _Unique_if<T>::_Unknown_bound
+        make_unique(size_t n) {
+            typedef typename remove_extent<T>::type U;
+            return unique_ptr<T>(new U[n]());
+        }
+
+    template<class T, class... Args>
+        typename _Unique_if<T>::_Known_bound
+        make_unique(Args&&...) = delete;
+}
 #endif
diff -Naur nzbget-17.0/linux/build-nzbget nzbget-17.0.patched/linux/build-nzbget
--- nzbget-17.0/linux/build-nzbget	2016-07-27 09:46:04.000000000 -0400
+++ nzbget-17.0.patched/linux/build-nzbget	2016-08-02 13:23:37.976934768 -0400
@@ -281,25 +281,25 @@
     case "$TOOLKIND-$CONFIG" in
         buildroot-debug|buildroot-debug-strip)
             LIBPREF="$STAGING" LDFLAGS="-static $STRIP" \
-                CXXFLAGS="-std=c++14 -g -fasynchronous-unwind-tables" \
+                CXXFLAGS="-std=c++11 -g -fasynchronous-unwind-tables" \
                 LIBS="-lcrypto -ldl -lz -lubacktrace" \
                 ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug
             ;;
         buildroot-release|buildroot-release-nostrip)
             LIBPREF="$STAGING" LDFLAGS="-static $STRIP" \
-                CXXFLAGS="-std=c++14 -O2" \
+                CXXFLAGS="-std=c++11 -O2" \
                 LIBS="-lcrypto -ldl -lz" \
                 ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME
             ;;
         crossgcc-debug|crossgcc-debug-strip)
             LIBPREF="$STAGING" LDFLAGS="-static $STRIP" \
-                CXXFLAGS="-std=c++14 -g -fasynchronous-unwind-tables" \
+                CXXFLAGS="-std=c++11 -g -fasynchronous-unwind-tables" \
                 PKG_CONFIG_PATH="$STAGING/lib/pkgconfig" \
                 ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME --enable-debug
                 ;;
         crossgcc-release|crossgcc-release-nostrip)
             LIBPREF="$STAGING" LDFLAGS="-static $STRIP" \
-                CXXFLAGS="-std=c++14 -O2" \
+                CXXFLAGS="-std=c++11 -O2" \
                 PKG_CONFIG_PATH="$STAGING/lib/pkgconfig" \
                 ./configure --disable-dependency-tracking --host=$ARCH-$TOOLNAME
                 ;;
@@ -315,7 +315,7 @@
             OPTIM="-O2"
         fi
 
-        $ARCH-$TOOLNAME-g++ -std=c++14 -DHAVE_CONFIG_H \
+        $ARCH-$TOOLNAME-g++ -std=c++11 -DHAVE_CONFIG_H \
             -I. -I$STAGING/include -I$STAGING/include/libxml2 \
             -g $OPTIM daemon/main/nzbget.h -o nzbget.h.gch
     fi
diff -Naur nzbget-17.0/Makefile.in nzbget-17.0.patched/Makefile.in
--- nzbget-17.0/Makefile.in	2016-07-27 09:46:21.000000000 -0400
+++ nzbget-17.0.patched/Makefile.in	2016-08-02 13:41:43.380297755 -0400
@@ -371,7 +371,7 @@
 EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 GREP = @GREP@
-HAVE_CXX14 = @HAVE_CXX14@
+HAVE_CXX11 = @HAVE_CXX11@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
