From 538dbfe585938916aef3194fd69c345332aa3ce0 Mon Sep 17 00:00:00 2001
From: hbristow <hilton.bristow@gmail.com>
Date: Sat, 29 Jun 2013 14:24:53 -0700
Subject: [PATCH] Now compiling under much more strigent warnings, with Clang
 and optional C++11 support

---
 cmake/OpenCVCompilerOptions.cmake             |  7 +-
 modules/matlab/CMakeLists.txt                 |  4 +-
 modules/matlab/generator/filters.py           |  8 +--
 .../matlab/generator/templates/functional.cpp |  4 ++
 .../templates/template_function_base.cpp      | 17 +++--
 modules/matlab/include/bridge.hpp             | 72 +++++++++----------
 modules/matlab/test/test_compiler.cpp         |  1 -
 7 files changed, 62 insertions(+), 51 deletions(-)

diff --git a/cmake/OpenCVCompilerOptions.cmake b/cmake/OpenCVCompilerOptions.cmake
index a71bcf06e3..cc4fffc69a 100644
--- a/cmake/OpenCVCompilerOptions.cmake
+++ b/cmake/OpenCVCompilerOptions.cmake
@@ -32,6 +32,11 @@ set(OPENCV_EXTRA_EXE_LINKER_FLAGS "")
 set(OPENCV_EXTRA_EXE_LINKER_FLAGS_RELEASE "")
 set(OPENCV_EXTRA_EXE_LINKER_FLAGS_DEBUG "")
 
+# if Apple and Clang, enable C++11 support :)
+if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
+  set(OPENCV_EXTRA_CXX_FLAGS "-std=c++11 -stdlib=libc++")
+endif()
+
 macro(add_extra_compiler_option option)
   if(CMAKE_BUILD_TYPE)
     set(CMAKE_TRY_COMPILE_CONFIGURATION ${CMAKE_BUILD_TYPE})
@@ -294,4 +299,4 @@ if(MSVC)
   if(NOT ENABLE_NOISY_WARNINGS)
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4251") #class 'std::XXX' needs to have dll-interface to be used by clients of YYY
   endif()
-endif()
\ No newline at end of file
+endif()
diff --git a/modules/matlab/CMakeLists.txt b/modules/matlab/CMakeLists.txt
index 2185904af5..f0258a10ad 100644
--- a/modules/matlab/CMakeLists.txt
+++ b/modules/matlab/CMakeLists.txt
@@ -58,7 +58,7 @@ set(HDR_PARSER_PATH ${CMAKE_CURRENT_SOURCE_DIR}/../python/src2)
 prepend("-I" MEX_INCLUDE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}/include)
 prepend("-L" MEX_LIB_DIR  ${CMAKE_BINARY_DIR}/lib)
 prepend("-l" MEX_LIBS opencv_core)
-set(MEX_OPTS "-largeArrayDims")
+set(MEX_OPTS -largeArrayDims)
 
 if (ENABLE_SOLUTION_FOLDERS)
     set_target_properties(${the_module} PROPERTIES FOLDER "Matlab bindings")
@@ -118,7 +118,7 @@ if (NOT MEX_WORKS)
                 ${CMAKE_CURRENT_SOURCE_DIR}/test/test_compiler.cpp
         WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/junk
         ERROR_VARIABLE MEX_ERROR
-        OUTPUT_QUIET
+        #OUTPUT_QUIET
     )
 
     if (MEX_ERROR)
diff --git a/modules/matlab/generator/filters.py b/modules/matlab/generator/filters.py
index 1d2beff05b..dcb8a891d3 100644
--- a/modules/matlab/generator/filters.py
+++ b/modules/matlab/generator/filters.py
@@ -12,9 +12,9 @@ def inputs(args):
     except:
       return [arg for arg in args if arg.I]
 
-def ninputs(args):
+def ninputs(fun):
     '''Counts the number of input arguments in the input list'''
-    return len(inputs(args))
+    return len(inputs(fun.req)) + len(inputs(fun.opt))
 
 def outputs(args):
     '''Determines whether any of the given arguments is an output
@@ -39,9 +39,9 @@ def void(arg):
 def flip(arg):
     return not arg
 
-def noutputs(args):
+def noutputs(fun):
     '''Counts the number of output arguments in the input list'''
-    return len(outputs(args))
+    return int(not void(fun.rtp)) + len(outputs(fun.req)) + len(outputs(fun.opt))
 
 def convertibleToInt(string):
     salt = '1+'
diff --git a/modules/matlab/generator/templates/functional.cpp b/modules/matlab/generator/templates/functional.cpp
index 3daf1b8d60..a478a73a82 100644
--- a/modules/matlab/generator/templates/functional.cpp
+++ b/modules/matlab/generator/templates/functional.cpp
@@ -29,6 +29,7 @@
 // create a full function invocation
 {%- macro generate(fun) -%}
 
+  {% if fun|ninputs or fun|noutputs %}
   // unpack the arguments
   {# ----------- Inputs ------------- #}
   {% for arg in fun.req|inputs %}
@@ -47,6 +48,7 @@
   {% if not fun.rtp|void %}
   {{fun.rtp}} retval;
   {% endif %}
+  {% endif %}
 
   // call the opencv function
   // [out =] namespace.fun(src1, ..., srcn, dst1, ..., dstn, opt1, ..., optn);
@@ -60,6 +62,7 @@
     mexErrMsgTxt("Uncaught exception occurred in {{fun.name}}");
   }
 
+  {% if fun|noutputs %}
   // assign the outputs into the bridge
   {% if not fun.rtp|void %}
   outputs[0] = retval;
@@ -70,5 +73,6 @@
   {% for opt in fun.opt|outputs %}
   outputs[{{loop.index0 + fun.rtp|void|not + fun.req|outputs|length}}] = {{opt.name}};
   {% endfor %}
+  {% endif %}
   
 {% endmacro %}
diff --git a/modules/matlab/generator/templates/template_function_base.cpp b/modules/matlab/generator/templates/template_function_base.cpp
index 98bafd2ea6..2b6a59a514 100644
--- a/modules/matlab/generator/templates/template_function_base.cpp
+++ b/modules/matlab/generator/templates/template_function_base.cpp
@@ -26,26 +26,29 @@ using namespace cv;
  *   nrhs - number of input arguments
  *   prhs - pointers to input arguments
  */
-void mexFunction(int nlhs, mxArray* plhs[],
-                 int nrhs, const mxArray* prhs[]) {
+void mexFunction(int nlhs, mxArray*{% if fun|noutputs %} plhs[]{% else %}*{% endif %},
+                 int nrhs, const mxArray*{% if fun|ninputs %} prhs[]{% else %}*{% endif %}) {
 
   // assertions
   conditionalError(nrhs >= {{fun.req|length - fun.req|only|outputs|length}}, "Too few required input arguments specified");
   conditionalError(nrhs <= {{fun.req|length + fun.opt|length - fun.req|only|outputs|length - fun.opt|only|outputs|length}}, "Too many input arguments specified");
   conditionalError(nlhs <= {{ fun.rtp|void|not + fun.req|outputs|length + fun.opt|outputs|length}}, "Too many output arguments specified");
 
+  {% if fun|ninputs or fun|noutputs %}
   // setup
+  {% if fun|ninputs %}
   std::vector<Bridge> inputs(prhs, prhs+nrhs);
-  {% set noutputs = fun.rtp|void|not + fun.req|outputs|length + fun.opt|outputs|length %}
-  {%- if noutputs %}
-  std::vector<Bridge> outputs({{noutputs}});
+  {% endif -%}
+  {%- if fun|noutputs %}
+  std::vector<Bridge> outputs({{fun|noutputs}});
+  {% endif %}
   {% endif %}
 
   {{ functional.generate(fun) }}
 
-  {%- if noutputs %}
+  {%- if fun|noutputs %}
   // push the outputs back to matlab
-  for (size_t n = 0; n < nlhs; ++n) {
+  for (size_t n = 0; n < static_cast<size_t>(nlhs); ++n) {
     plhs[n] = outputs[n].toMxArray().releaseOwnership();
   }
   {% endif %}
diff --git a/modules/matlab/include/bridge.hpp b/modules/matlab/include/bridge.hpp
index c80e9b0584..05e32ed8e3 100644
--- a/modules/matlab/include/bridge.hpp
+++ b/modules/matlab/include/bridge.hpp
@@ -6,7 +6,7 @@
 #include <string>
 #include <opencv2/core.hpp>
 #include <opencv2/calib3d.hpp>
-#include <ext/hash_map>
+#include <unordered_map>
 
 /*
  * All recent versions of Matlab ship with the MKL library which contains
@@ -208,7 +208,7 @@ private:
   // this function is called exclusively from constructors!!
   template <typename Scalar>
   void fromMat(const cv::Mat& mat) {
-    mwSize dims[] = { mat.rows, mat.cols, mat.channels() };
+    mwSize dims[] = { static_cast<mwSize>(mat.rows), static_cast<mwSize>(mat.cols), static_cast<mwSize>(mat.channels()) };
     ptr_ = mxCreateNumericArray(3, dims, Matlab::Traits<Scalar>::ScalarType, Matlab::Traits<>::Real);
     owns_ = true;
     switch (mat.depth()) {
@@ -412,28 +412,28 @@ cv::Mat MxArray::toMat<Matlab::InheritType>() const {
 // ----------------------------------------------------------------------------
 
 template <typename InputScalar, typename OutputScalar>
-void deepCopyAndTranspose(const cv::Mat& src, MxArray& dst) {
+void deepCopyAndTranspose(const cv::Mat&, MxArray&) {
 }
 
 template <typename InputScalar, typename OutputScalar>
-void deepCopyAndTranspose(const MxArray& src, cv::Mat& dst) {
+void deepCopyAndTranspose(const MxArray&, cv::Mat&) {
 }
 
 template <> 
-void deepCopyAndTranspose<float, float>(const cv::Mat& src, MxArray& dst) {
+void deepCopyAndTranspose<float, float>(const cv::Mat&, MxArray&) {
 }
 
 template <> 
-void deepCopyAndTranspose<double, double>(const cv::Mat& src, MxArray& dst) {
+void deepCopyAndTranspose<double, double>(const cv::Mat&, MxArray&) {
 }
 
 template <> 
-void deepCopyAndTranspose<float, float>(const MxArray& src, cv::Mat& dst) {
+void deepCopyAndTranspose<float, float>(const MxArray&, cv::Mat&) {
   // use mkl
 }
 
 template <> 
-void deepCopyAndTranspose<double, double>(const MxArray& src, cv::Mat& dst) {
+void deepCopyAndTranspose<double, double>(const MxArray&, cv::Mat& ) {
   // use mkl
 }
 
@@ -535,7 +535,7 @@ public:
   // --------------------------------------------------------------------------
   //                           MATLAB TYPES
   // --------------------------------------------------------------------------
-  Bridge& operator=(const mxArray* obj) { return *this; }
+  Bridge& operator=(const mxArray*) { return *this; }
   Bridge(const mxArray* obj) : ptr_(obj) {}
   MxArray toMxArray() { return ptr_; }
   
@@ -548,29 +548,29 @@ public:
   // --------------------------------------------------------------------------
   
   // --------------------------- string  --------------------------------------
-  Bridge& operator=(const std::string& obj) { return *this; }
+  Bridge& operator=(const std::string& ) { return *this; }
   std::string toString() { 
     return ptr_.toString();
   }
   operator std::string() { return toString(); }
 
   // ---------------------------  bool   --------------------------------------
-  Bridge& operator=(const bool& obj) { return *this; }
+  Bridge& operator=(const bool& ) { return *this; }
   bool toBool() { return 0; }
   operator bool() { return toBool(); }
 
   // --------------------------- double  --------------------------------------
-  Bridge& operator=(const double& obj) { return *this; }
+  Bridge& operator=(const double& ) { return *this; }
   double toDouble() { return ptr_.scalar<double>(); }
   operator double() { return toDouble(); }
 
   // --------------------------- float  ---------------------------------------
-  Bridge& operator=(const float& obj) { return *this; }
+  Bridge& operator=(const float& ) { return *this; }
   float toFloat() { return ptr_.scalar<float>(); }
   operator float() { return toFloat(); }
 
   // ---------------------------   int   --------------------------------------
-  Bridge& operator=(const int& obj) { return *this; }
+  Bridge& operator=(const int& ) { return *this; }
   int toInt() { return ptr_.scalar<int>(); }
   operator int() { return toInt(); }
   
@@ -583,57 +583,57 @@ public:
   // --------------------------------------------------------------------------
 
   // --------------------------- cv::Mat --------------------------------------
-  Bridge& operator=(const cv::Mat& obj) { return *this; }
+  Bridge& operator=(const cv::Mat& ) { return *this; }
   cv::Mat toMat() const { return ptr_.toMat<Matlab::InheritType>(); }
   operator cv::Mat() const { return toMat(); }
   
   // --------------------------   Point  --------------------------------------
-  Bridge& operator=(const cv::Point& obj) { return *this; }
+  Bridge& operator=(const cv::Point& ) { return *this; }
   cv::Point toPoint() const { return cv::Point(); }
   operator cv::Point() const { return toPoint(); }
   
   // --------------------------   Point2f  ------------------------------------
-  Bridge& operator=(const cv::Point2f& obj) { return *this; }
+  Bridge& operator=(const cv::Point2f& ) { return *this; }
   cv::Point2f toPoint2f() const { return cv::Point2f(); }
   operator cv::Point2f() const { return toPoint2f(); }
   
   // --------------------------   Point2d  ------------------------------------
-  Bridge& operator=(const cv::Point2d& obj) { return *this; }
+  Bridge& operator=(const cv::Point2d& ) { return *this; }
   cv::Point2d toPoint2d() const { return cv::Point2d(); }
   operator cv::Point2d() const { return toPoint2d(); }
   
   // --------------------------   Size  ---------------------------------------
-  Bridge& operator=(const cv::Size& obj) { return *this; }
+  Bridge& operator=(const cv::Size& ) { return *this; }
   cv::Size toSize() const { return cv::Size(); }
   operator cv::Size() const { return toSize(); }
   
   // -------------------------- Moments  --------------------------------------
-  Bridge& operator=(const cv::Moments& obj) { return *this; }
+  Bridge& operator=(const cv::Moments& ) { return *this; }
   cv::Moments toMoments() const { return cv::Moments(); }
   operator cv::Moments() const { return toMoments(); }
   
   // --------------------------  Scalar  --------------------------------------
-  Bridge& operator=(const cv::Scalar& obj) { return *this; }
+  Bridge& operator=(const cv::Scalar& ) { return *this; }
   cv::Scalar toScalar() { return cv::Scalar(); }
   operator cv::Scalar() { return toScalar(); }
   
   // -------------------------- Rect  -----------------------------------------
-  Bridge& operator=(const cv::Rect& obj) { return *this; }
+  Bridge& operator=(const cv::Rect& ) { return *this; }
   cv::Rect toRect() { return cv::Rect(); }
   operator cv::Rect() { return toRect(); }
   
   // ---------------------- RotatedRect ---------------------------------------
-  Bridge& operator=(const cv::RotatedRect& obj) { return *this; }
+  Bridge& operator=(const cv::RotatedRect& ) { return *this; }
   cv::RotatedRect toRotatedRect() { return cv::RotatedRect(); }
   operator cv::RotatedRect() { return toRotatedRect(); }
   
   // ---------------------- TermCriteria --------------------------------------
-  Bridge& operator=(const cv::TermCriteria& obj) { return *this; }
+  Bridge& operator=(const cv::TermCriteria& ) { return *this; }
   cv::TermCriteria toTermCriteria() { return cv::TermCriteria(); }
   operator cv::TermCriteria() { return toTermCriteria(); }
   
   // ----------------------      RNG     --------------------------------------
-  Bridge& operator=(const cv::RNG& obj) { return *this; }
+  Bridge& operator=(const cv::RNG& ) { return *this; }
   /*! @brief explicit conversion to cv::RNG()
    *
    * Converts a bridge object to a cv::RNG(). We explicitly assert that
@@ -654,42 +654,42 @@ public:
   // --------------------------------------------------------------------------
   
   // -------------------- vector_Mat ------------------------------------------
-  Bridge& operator=(const vector_Mat& obj) { return *this; }
+  Bridge& operator=(const vector_Mat& ) { return *this; }
   vector_Mat toVectorMat() { return vector_Mat(); }
   operator vector_Mat() { return toVectorMat(); }
 
   // --------------------------- vector_int  ----------------------------------
-  Bridge& operator=(const vector_int& obj) { return *this; }
+  Bridge& operator=(const vector_int& ) { return *this; }
   vector_int toVectorInt() { return vector_int(); }
   operator vector_int() { return toVectorInt(); }
   
   // --------------------------- vector_float  --------------------------------
-  Bridge& operator=(const vector_float& obj) { return *this; }
+  Bridge& operator=(const vector_float& ) { return *this; }
   vector_float toVectorFloat() { return vector_float(); }
   operator vector_float() { return toVectorFloat(); }
   
   // --------------------------- vector_Rect  ---------------------------------
-  Bridge& operator=(const vector_Rect& obj) { return *this; }
+  Bridge& operator=(const vector_Rect& ) { return *this; }
   vector_Rect toVectorRect() { return vector_Rect(); }
   operator vector_Rect() { return toVectorRect(); }
   
   // --------------------------- vector_KeyPoint  -----------------------------
-  Bridge& operator=(const vector_KeyPoint& obj) { return *this; }
+  Bridge& operator=(const vector_KeyPoint& ) { return *this; }
   vector_KeyPoint toVectorKeyPoint() { return vector_KeyPoint(); }
   operator vector_KeyPoint() { return toVectorKeyPoint(); }
   
   // --------------------------- vector_String  -------------------------------
-  Bridge& operator=(const vector_String& obj) { return *this; }
+  Bridge& operator=(const vector_String& ) { return *this; }
   vector_String toVectorString() { return vector_String(); }
   operator vector_String() { return toVectorString(); }
   
   // ------------------------ vector_Point ------------------------------------
-  Bridge& operator=(const vector_Point& obj) { return *this; }
+  Bridge& operator=(const vector_Point& ) { return *this; }
   vector_Point toVectorPoint() { return vector_Point(); }
   operator vector_Point() { return toVectorPoint(); }
   
   // ------------------------ vector_uchar ------------------------------------
-  Bridge& operator=(const vector_uchar& obj) { return *this; }
+  Bridge& operator=(const vector_uchar& ) { return *this; }
   vector_uchar toVectorUchar() { return vector_uchar(); }
   operator vector_uchar() { return toVectorUchar(); }
   
@@ -702,17 +702,17 @@ public:
   // --------------------------------------------------------------------------
 
   // ---------------------------   Ptr_StereoBM   -----------------------------
-  Bridge& operator=(const Ptr_StereoBM& obj) { return *this; }
+  Bridge& operator=(const Ptr_StereoBM& ) { return *this; }
   Ptr_StereoBM toPtrStereoBM() { return Ptr_StereoBM(); }
   operator Ptr_StereoBM() { return toPtrStereoBM(); }
 
   // ---------------------------   Ptr_StereoSGBM   ---------------------------
-  Bridge& operator=(const Ptr_StereoSGBM& obj) { return *this; }
+  Bridge& operator=(const Ptr_StereoSGBM& ) { return *this; }
   Ptr_StereoSGBM toPtrStereoSGBM() { return Ptr_StereoSGBM(); }
   operator Ptr_StereoSGBM() { return toPtrStereoSGBM(); }
 
   // ---------------------------   Ptr_FeatureDetector   ----------------------
-  Bridge& operator=(const Ptr_FeatureDetector& obj) { return *this; }
+  Bridge& operator=(const Ptr_FeatureDetector& ) { return *this; }
   Ptr_FeatureDetector toPtrFeatureDetector() { return Ptr_FeatureDetector(); }
   operator Ptr_FeatureDetector() { return toPtrFeatureDetector(); }
 
diff --git a/modules/matlab/test/test_compiler.cpp b/modules/matlab/test/test_compiler.cpp
index 78995e2b1a..660aff2967 100644
--- a/modules/matlab/test/test_compiler.cpp
+++ b/modules/matlab/test/test_compiler.cpp
@@ -8,7 +8,6 @@
  * Copyright 2013 The OpenCV Foundation
  */
 #include "mex.h"
-#include "bridge.hpp"
 #include <vector>
 
 /*