From 7f73b105ca6f3380472a5dabb5ad7485baf2d86a Mon Sep 17 00:00:00 2001
From: Alexander Alekhin <alexander.alekhin@intel.com>
Date: Thu, 23 Aug 2018 18:17:04 +0300
Subject: [PATCH] core: std::string more changes

---
 modules/core/include/opencv2/core/cvstd.hpp   | 33 +++++++++++++++++++
 .../core/include/opencv2/core/persistence.hpp |  1 -
 modules/core/src/command_line_parser.cpp      |  7 +---
 modules/core/src/ocl.cpp                      |  7 +---
 modules/core/src/persistence_cpp.cpp          |  5 ---
 modules/core/src/system.cpp                   |  2 +-
 modules/dnn/src/dnn.cpp                       | 10 +++---
 .../dnn/src/layers/detection_output_layer.cpp |  2 +-
 modules/dnn/src/layers/eltwise_layer.cpp      |  2 +-
 modules/dnn/src/layers/pooling_layer.cpp      |  2 +-
 modules/dnn/src/layers/recurrent_layers.cpp   |  6 ++--
 11 files changed, 47 insertions(+), 30 deletions(-)

diff --git a/modules/core/include/opencv2/core/cvstd.hpp b/modules/core/include/opencv2/core/cvstd.hpp
index 54754c8eae..69846f7ab6 100644
--- a/modules/core/include/opencv2/core/cvstd.hpp
+++ b/modules/core/include/opencv2/core/cvstd.hpp
@@ -452,6 +452,39 @@ class CV_EXPORTS FileNode; //for string constructor from FileNode
 
 typedef std::string String;
 
+#ifndef OPENCV_DISABLE_STRING_LOWER_UPPER_CONVERSIONS
+
+//! @cond IGNORED
+namespace details {
+// std::tolower is int->int
+static inline char char_tolower(char ch)
+{
+    return (char)std::tolower((int)ch);
+}
+// std::toupper is int->int
+static inline char char_toupper(char ch)
+{
+    return (char)std::toupper((int)ch);
+}
+} // namespace details
+//! @endcond
+
+static inline std::string toLowerCase(const std::string& str)
+{
+    std::string result(str);
+    std::transform(result.begin(), result.end(), result.begin(), details::char_tolower);
+    return result;
+}
+
+static inline std::string toUpperCase(const std::string& str)
+{
+    std::string result(str);
+    std::transform(result.begin(), result.end(), result.begin(), details::char_toupper);
+    return result;
+}
+
+#endif // OPENCV_DISABLE_STRING_LOWER_UPPER_CONVERSIONS
+
 //! @} core_basic
 } // cv
 
diff --git a/modules/core/include/opencv2/core/persistence.hpp b/modules/core/include/opencv2/core/persistence.hpp
index ed608c1494..790dde83f6 100644
--- a/modules/core/include/opencv2/core/persistence.hpp
+++ b/modules/core/include/opencv2/core/persistence.hpp
@@ -719,7 +719,6 @@ CV_EXPORTS void writeScalar( FileStorage& fs, const String& value );
 CV_EXPORTS void read(const FileNode& node, int& value, int default_value);
 CV_EXPORTS void read(const FileNode& node, float& value, float default_value);
 CV_EXPORTS void read(const FileNode& node, double& value, double default_value);
-CV_EXPORTS void read(const FileNode& node, String& value, const String& default_value);
 CV_EXPORTS void read(const FileNode& node, std::string& value, const std::string& default_value);
 CV_EXPORTS void read(const FileNode& node, Mat& mat, const Mat& default_mat = Mat() );
 CV_EXPORTS void read(const FileNode& node, SparseMat& mat, const SparseMat& default_mat = SparseMat() );
diff --git a/modules/core/src/command_line_parser.cpp b/modules/core/src/command_line_parser.cpp
index 766835fe1d..6ef24d2cd0 100644
--- a/modules/core/src/command_line_parser.cpp
+++ b/modules/core/src/command_line_parser.cpp
@@ -72,14 +72,9 @@ static const char* get_type_name(int type)
     return "unknown";
 }
 
-// std::tolower is int->int
-static char char_tolower(char ch)
-{
-    return (char)std::tolower((int)ch);
-}
 static bool parse_bool(std::string str)
 {
-    std::transform(str.begin(), str.end(), str.begin(), char_tolower);
+    std::transform(str.begin(), str.end(), str.begin(), details::char_tolower);
     std::istringstream is(str);
     bool b;
     is >> (str.size() > 1 ? std::boolalpha : std::noboolalpha) >> b;
diff --git a/modules/core/src/ocl.cpp b/modules/core/src/ocl.cpp
index 05f128baa7..95d51f9cc5 100644
--- a/modules/core/src/ocl.cpp
+++ b/modules/core/src/ocl.cpp
@@ -1691,11 +1691,6 @@ static cl_device_id selectOpenCLDevice()
     return NULL;
 }
 #else
-// std::tolower is int->int
-static char char_tolower(char ch)
-{
-    return (char)std::tolower((int)ch);
-}
 static cl_device_id selectOpenCLDevice()
 {
     std::string platform, deviceName;
@@ -1780,7 +1775,7 @@ static cl_device_id selectOpenCLDevice()
     {
         int deviceType = 0;
         std::string tempStrDeviceType = deviceTypes[t];
-        std::transform(tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), char_tolower);
+        std::transform(tempStrDeviceType.begin(), tempStrDeviceType.end(), tempStrDeviceType.begin(), details::char_tolower);
 
         if (tempStrDeviceType == "gpu" || tempStrDeviceType == "dgpu" || tempStrDeviceType == "igpu")
             deviceType = Device::TYPE_GPU;
diff --git a/modules/core/src/persistence_cpp.cpp b/modules/core/src/persistence_cpp.cpp
index 29984dba27..e584a130dd 100644
--- a/modules/core/src/persistence_cpp.cpp
+++ b/modules/core/src/persistence_cpp.cpp
@@ -667,11 +667,6 @@ void read(const FileNode& node, double& value, double default_value)
         CV_NODE_IS_REAL(node.node->tag) ? node.node->data.f : std::numeric_limits<double>::max();
 }
 
-void read(const FileNode& node, String& value, const String& default_value)
-{
-    value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? String(node.node->data.str.ptr) : String();
-}
-
 void read(const FileNode& node, std::string& value, const std::string& default_value)
 {
     value = !node.node ? default_value : CV_NODE_IS_STRING(node.node->tag) ? std::string(node.node->data.str.ptr) : default_value;
diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp
index 95525e7c9b..bfa7a13cfb 100644
--- a/modules/core/src/system.cpp
+++ b/modules/core/src/system.cpp
@@ -1970,7 +1970,7 @@ public:
             const Ipp64u minorFeatures = 0;
 #endif
 
-            env = env.toLowerCase();
+            env = toLowerCase(env);
             if(env.substr(0, 2) == "ne")
             {
                 useIPP_NE = true;
diff --git a/modules/dnn/src/dnn.cpp b/modules/dnn/src/dnn.cpp
index ad4741d008..9dda8c48c3 100644
--- a/modules/dnn/src/dnn.cpp
+++ b/modules/dnn/src/dnn.cpp
@@ -3329,7 +3329,7 @@ void LayerFactory::registerLayer(const String &type, Constructor constructor)
     CV_TRACE_ARG_VALUE(type, "type", type.c_str());
 
     cv::AutoLock lock(getLayerFactoryMutex());
-    String type_ = type.toLowerCase();
+    String type_ = toLowerCase(type);
     LayerFactory_Impl::iterator it = getLayerFactoryImpl().find(type_);
 
     if (it != getLayerFactoryImpl().end())
@@ -3347,7 +3347,7 @@ void LayerFactory::unregisterLayer(const String &type)
     CV_TRACE_ARG_VALUE(type, "type", type.c_str());
 
     cv::AutoLock lock(getLayerFactoryMutex());
-    String type_ = type.toLowerCase();
+    String type_ = toLowerCase(type);
 
     LayerFactory_Impl::iterator it = getLayerFactoryImpl().find(type_);
     if (it != getLayerFactoryImpl().end())
@@ -3365,7 +3365,7 @@ Ptr<Layer> LayerFactory::createLayerInstance(const String &type, LayerParams& pa
     CV_TRACE_ARG_VALUE(type, "type", type.c_str());
 
     cv::AutoLock lock(getLayerFactoryMutex());
-    String type_ = type.toLowerCase();
+    String type_ = toLowerCase(type);
     LayerFactory_Impl::const_iterator it = getLayerFactoryImpl().find(type_);
 
     if (it != getLayerFactoryImpl().end())
@@ -3402,7 +3402,7 @@ BackendWrapper::~BackendWrapper() {}
 
 Net readNet(const String& _model, const String& _config, const String& _framework)
 {
-    String framework = _framework.toLowerCase();
+    String framework = toLowerCase(_framework);
     String model = _model;
     String config = _config;
     const std::string modelExt = model.substr(model.rfind('.') + 1);
@@ -3447,7 +3447,7 @@ Net readNet(const String& _model, const String& _config, const String& _framewor
 Net readNet(const String& _framework, const std::vector<uchar>& bufferModel,
             const std::vector<uchar>& bufferConfig)
 {
-    String framework = _framework.toLowerCase();
+    String framework = toLowerCase(_framework);
     if (framework == "caffe")
         return readNetFromCaffe(bufferConfig, bufferModel);
     else if (framework == "tensorflow")
diff --git a/modules/dnn/src/layers/detection_output_layer.cpp b/modules/dnn/src/layers/detection_output_layer.cpp
index 42a6a6c715..abfa0c1b23 100644
--- a/modules/dnn/src/layers/detection_output_layer.cpp
+++ b/modules/dnn/src/layers/detection_output_layer.cpp
@@ -163,7 +163,7 @@ public:
 
     void getCodeType(const LayerParams &params)
     {
-        String codeTypeString = params.get<String>("code_type").toLowerCase();
+        String codeTypeString = toLowerCase(params.get<String>("code_type"));
         if (codeTypeString == "center_size")
             _codeType = "CENTER_SIZE";
         else
diff --git a/modules/dnn/src/layers/eltwise_layer.cpp b/modules/dnn/src/layers/eltwise_layer.cpp
index 567d598416..b1a3493a90 100644
--- a/modules/dnn/src/layers/eltwise_layer.cpp
+++ b/modules/dnn/src/layers/eltwise_layer.cpp
@@ -71,7 +71,7 @@ public:
         op = SUM;
         if (params.has("operation"))
         {
-            String operation = params.get<String>("operation").toLowerCase();
+            String operation = toLowerCase(params.get<String>("operation"));
             if (operation == "prod")
                 op = PROD;
             else if (operation == "sum")
diff --git a/modules/dnn/src/layers/pooling_layer.cpp b/modules/dnn/src/layers/pooling_layer.cpp
index 573565d025..200751d9b2 100644
--- a/modules/dnn/src/layers/pooling_layer.cpp
+++ b/modules/dnn/src/layers/pooling_layer.cpp
@@ -76,7 +76,7 @@ public:
         if (params.has("pool") || params.has("kernel_size") ||
             params.has("kernel_w") || params.has("kernel_h"))
         {
-            String pool = params.get<String>("pool", "max").toLowerCase();
+            String pool = toLowerCase(params.get<String>("pool", "max"));
             if (pool == "max")
                 type = MAX;
             else if (pool == "ave")
diff --git a/modules/dnn/src/layers/recurrent_layers.cpp b/modules/dnn/src/layers/recurrent_layers.cpp
index b356b7627c..15f791a0b0 100644
--- a/modules/dnn/src/layers/recurrent_layers.cpp
+++ b/modules/dnn/src/layers/recurrent_layers.cpp
@@ -349,16 +349,16 @@ Ptr<LSTMLayer> LSTMLayer::create(const LayerParams& params)
 
 int LSTMLayer::inputNameToIndex(String inputName)
 {
-    if (inputName.toLowerCase() == "x")
+    if (toLowerCase(inputName) == "x")
         return 0;
     return -1;
 }
 
 int LSTMLayer::outputNameToIndex(const String& outputName)
 {
-    if (outputName.toLowerCase() == "h")
+    if (toLowerCase(outputName) == "h")
         return 0;
-    else if (outputName.toLowerCase() == "c")
+    else if (toLowerCase(outputName) == "c")
         return 1;
     return -1;
 }
-- 
2.18.0