Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Sharybin <sergey.vfx@gmail.com>2016-02-05 11:09:39 +0300
committerSergey Sharybin <sergey.vfx@gmail.com>2016-02-06 21:19:20 +0300
commitf25f7c803020b9341e49e898abe94917c3235515 (patch)
tree17754b6b7f4d4037ba4cadb2a55657952c1aeb79 /intern/cycles
parent7623d3e071e6356ce4519073b1a29d984ba86cd9 (diff)
Cycles: Re-implement some utilities to avoid use of boost
The title says it all actually, the idea is to make Cycles only requiring Boost via 3rd party dependencies like OIIO and OSL. So now there are only few places which still uses Boost: - Foreach, function bindings and threading primitives. Those we can easily get rid with C++11 bump (which seems inevitable sooner or later if we'll want ot use newer LLVM for OSL), - Networking devices There's no quick solution for those currently, but there are some patches around which improves serialization. Reviewers: juicyfruit, mont29, campbellbarton, brecht, dingto Reviewed By: brecht, dingto Differential Revision: https://developer.blender.org/D1764
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/device/device_cpu.cpp11
-rw-r--r--intern/cycles/render/shader.h11
-rw-r--r--intern/cycles/util/CMakeLists.txt1
-rw-r--r--intern/cycles/util/util_optimization.h5
-rw-r--r--intern/cycles/util/util_path.cpp559
-rw-r--r--intern/cycles/util/util_path.h5
-rw-r--r--intern/cycles/util/util_set.h23
-rw-r--r--intern/cycles/util/util_string.cpp103
-rw-r--r--intern/cycles/util/util_string.h11
-rw-r--r--intern/cycles/util/util_system.cpp14
-rw-r--r--intern/cycles/util/util_time.cpp3
-rw-r--r--intern/cycles/util/util_windows.h37
12 files changed, 700 insertions, 83 deletions
diff --git a/intern/cycles/device/device_cpu.cpp b/intern/cycles/device/device_cpu.cpp
index 83447b7a5f3..676b1279a80 100644
--- a/intern/cycles/device/device_cpu.cpp
+++ b/intern/cycles/device/device_cpu.cpp
@@ -19,15 +19,8 @@
/* So ImathMath is included before our kernel_cpu_compat. */
#ifdef WITH_OSL
-# if defined(_MSC_VER)
-/* Prevent OSL from polluting the context with weird macros from windows.h.
- * TODO(sergey): Ideally it's only enough to have class/struct declarations in
- * the header and skip header include here.
- */
-# define NOGDI
-# define NOMINMAX
-# define WIN32_LEAN_AND_MEAN
-# endif
+/* So no context pollution happens from indirectly included windows.h */
+# include "util_windows.h"
# include <OSL/oslexec.h>
#endif
diff --git a/intern/cycles/render/shader.h b/intern/cycles/render/shader.h
index cc83ad03277..6f4fd0e7797 100644
--- a/intern/cycles/render/shader.h
+++ b/intern/cycles/render/shader.h
@@ -18,15 +18,8 @@
#define __SHADER_H__
#ifdef WITH_OSL
-# if defined(_MSC_VER)
-/* Prevent OSL from polluting the context with weird macros from windows.h.
- * TODO(sergey): Ideally it's only enough to have class/struct declarations in
- * the header and skip header include here.
- */
-# define NOGDI
-# define NOMINMAX
-# define WIN32_LEAN_AND_MEAN
-# endif
+/* So no context pollution happens from indirectly included windows.h */
+# include "util_windows.h"
# include <OSL/oslexec.h>
#endif
diff --git a/intern/cycles/util/CMakeLists.txt b/intern/cycles/util/CMakeLists.txt
index 9cf949b622e..8367d21bfc6 100644
--- a/intern/cycles/util/CMakeLists.txt
+++ b/intern/cycles/util/CMakeLists.txt
@@ -73,6 +73,7 @@ set(SRC_HEADERS
util_types.h
util_vector.h
util_view.h
+ util_windows.h
util_xml.h
)
diff --git a/intern/cycles/util/util_optimization.h b/intern/cycles/util/util_optimization.h
index b1f9ee6af69..1fef0bd044e 100644
--- a/intern/cycles/util/util_optimization.h
+++ b/intern/cycles/util/util_optimization.h
@@ -111,10 +111,7 @@
/* MinGW64 has conflicting declarations for these SSE headers in <windows.h>.
* Since we can't avoid including <windows.h>, better only include that */
-#define NOGDI
-#define NOMINMAX
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
+#include "util_windows.h"
#endif
diff --git a/intern/cycles/util/util_path.cpp b/intern/cycles/util/util_path.cpp
index 06be607b8e9..e7a61350fbc 100644
--- a/intern/cycles/util/util_path.cpp
+++ b/intern/cycles/util/util_path.cpp
@@ -21,28 +21,297 @@
#include <OpenImageIO/strutil.h>
#include <OpenImageIO/sysutil.h>
+
OIIO_NAMESPACE_USING
#include <stdio.h>
-#include <boost/filesystem.hpp>
-#include <boost/algorithm/string.hpp>
+#include <sys/stat.h>
+
+#if defined(_WIN32)
+# define DIR_SEP '\\'
+# define DIR_SEP_ALT '/'
+# include <direct.h>
+#else
+# define DIR_SEP '/'
+# define DIR_SEP_ALT '\\'
+# include <dirent.h>
+#endif
+
+#ifdef HAVE_SHLWAPI_H
+# include <shlwapi.h>
+#endif
+
+#include "util_windows.h"
CCL_NAMESPACE_BEGIN
+#ifdef _WIN32
+# if defined(_MSC_VER) || defined(__MINGW64__)
+typedef struct _stat64 path_stat_t;
+# elif defined(__MINGW32__)
+typedef struct _stati64 path_stat_t;
+# else
+typedef struct _stat path_stat_t;
+# endif
+# ifndef S_ISDIR
+# define S_ISDIR(x) (((x) & _S_IFDIR) == _S_IFDIR)
+# endif
+# define mkdir(path, mode) _mkdir(path)
+#else
+typedef struct stat path_stat_t;
+#endif
+
static string cached_path = "";
static string cached_user_path = "";
-static boost::filesystem::path to_boost(const string& path)
-{
- return boost::filesystem::path(path.c_str());
-}
+namespace {
+
+#ifdef _WIN32
+class directory_iterator {
+public:
+ class path_info {
+ public:
+ path_info(const string& path,
+ const WIN32_FIND_DATAW& find_data)
+ : path_(path),
+ find_data_(find_data)
+ {
+ }
+
+ string path() {
+ return path_join(path_, string_from_wstring(find_data_.cFileName));
+ }
+ protected:
+ const string& path_;
+ const WIN32_FIND_DATAW& find_data_;
+ };
+
+ directory_iterator()
+ : path_info_("", find_data_),
+ h_find_(INVALID_HANDLE_VALUE)
+ {
+ }
+
+ directory_iterator(const string& path)
+ : path_(path),
+ path_info_(path, find_data_)
+ {
+ string wildcard = path;
+ if(wildcard[wildcard.size() - 1] != DIR_SEP) {
+ wildcard += DIR_SEP;
+ }
+ wildcard += "*";
+ h_find_ = FindFirstFileW(string_to_wstring(wildcard).c_str(),
+ &find_data_);
+ if(h_find_ != INVALID_HANDLE_VALUE) {
+ skip_dots();
+ }
+ }
+
+ ~directory_iterator()
+ {
+ if(h_find_ != INVALID_HANDLE_VALUE) {
+ FindClose(h_find_);
+ }
+ }
+
+ directory_iterator& operator++()
+ {
+ step();
+ return *this;
+ }
+
+ path_info* operator-> ()
+ {
+ return &path_info_;
+ }
+
+ bool operator!=(const directory_iterator& other)
+ {
+ return h_find_ != other.h_find_;
+ }
+
+protected:
+ bool step()
+ {
+ if(do_step()) {
+ return skip_dots();
+ }
+ return false;
+ }
+
+ bool do_step()
+ {
+ if(h_find_ != INVALID_HANDLE_VALUE) {
+ bool result = FindNextFileW(h_find_, &find_data_) == TRUE;
+ if(!result) {
+ FindClose(h_find_);
+ h_find_ = INVALID_HANDLE_VALUE;
+ }
+ return result;
+ }
+ return false;
+ }
+
+ bool skip_dots()
+ {
+ while(wcscmp(find_data_.cFileName, L".") == 0 ||
+ wcscmp(find_data_.cFileName, L"..") == 0)
+ {
+ if(!do_step()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ string path_;
+ path_info path_info_;
+ WIN32_FIND_DATAW find_data_;
+ HANDLE h_find_;
+};
+#else /* _WIN32 */
+
+class directory_iterator {
+public:
+ class path_info {
+ public:
+ path_info(const string& path)
+ : path_(path)
+ {
+ }
-static string from_boost(const boost::filesystem::path& path)
+ string path() {
+ return path_join(path_, entry_->d_name);
+ }
+
+ void current_entry_set(const struct dirent *entry)
+ {
+ entry_ = entry;
+ }
+ protected:
+ const string& path_;
+ const struct dirent *entry_;
+ };
+
+ directory_iterator()
+ : path_info_(""),
+ name_list_(NULL),
+ num_entries_(-1),
+ cur_entry_(-1)
+ {
+ }
+
+ directory_iterator(const string& path)
+ : path_(path),
+ path_info_(path_),
+ cur_entry_(0)
+ {
+ num_entries_ = scandir(path.c_str(),
+ &name_list_,
+ NULL,
+ alphasort);
+ if(num_entries_ < 0) {
+ perror("scandir");
+ }
+ else {
+ skip_dots();
+ }
+ }
+
+ ~directory_iterator()
+ {
+ destroy_name_list();
+ }
+
+ directory_iterator& operator++()
+ {
+ step();
+ return *this;
+ }
+
+ path_info* operator-> ()
+ {
+ path_info_.current_entry_set(name_list_[cur_entry_]);
+ return &path_info_;
+ }
+
+ bool operator!=(const directory_iterator& other)
+ {
+ return name_list_ != other.name_list_;
+ }
+
+protected:
+ bool step()
+ {
+ if(do_step()) {
+ return skip_dots();
+ }
+ return false;
+ }
+
+ bool do_step()
+ {
+ ++cur_entry_;
+ if(cur_entry_ >= num_entries_) {
+ destroy_name_list();
+ return false;
+ }
+ return true;
+ }
+
+ /* Skip . and .. folders. */
+ bool skip_dots()
+ {
+ while(strcmp(name_list_[cur_entry_]->d_name, ".") == 0 ||
+ strcmp(name_list_[cur_entry_]->d_name, "..") == 0)
+ {
+ if(!step()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ void destroy_name_list()
+ {
+ if(name_list_ == NULL) {
+ return;
+ }
+ for(int i = 0; i < num_entries_; ++i) {
+ free(name_list_[i]);
+ }
+ free(name_list_);
+ name_list_ = NULL;
+ }
+
+ string path_;
+ path_info path_info_;
+ struct dirent **name_list_;
+ int num_entries_, cur_entry_;
+};
+
+#endif /* _WIN32 */
+
+size_t find_last_slash(const string& path)
{
- return path.string().c_str();
+ for(size_t i = 0; i < path.size(); ++i) {
+ size_t index = path.size() - 1 - i;
+#ifdef _WIN32
+ if(path[index] == DIR_SEP || path[index] == DIR_SEP_ALT)
+#else
+ if(path[index] == DIR_SEP)
+#endif
+ {
+ return index;
+ }
+ }
+ return string::npos;
}
+} /* namespace */
+
static char *path_specials(const string& sub)
{
static bool env_init = false;
@@ -90,49 +359,237 @@ string path_user_get(const string& sub)
string path_filename(const string& path)
{
- return from_boost(to_boost(path).filename());
+ size_t index = find_last_slash(path);
+ if(index != string::npos) {
+ /* Corner cases to match boost behavior. */
+#ifndef _WIN32
+ if(index == 0 && path.size() == 1) {
+ return path;
+ }
+#endif
+ if(index == path.size() - 1) {
+#ifdef _WIN32
+ if(index == 2) {
+ return string(1, DIR_SEP);
+ }
+#endif
+ return ".";
+ }
+ return path.substr(index + 1, path.size() - index - 1);
+ }
+ return path;
}
string path_dirname(const string& path)
{
- return from_boost(to_boost(path).parent_path());
+ size_t index = find_last_slash(path);
+ if(index != string::npos) {
+#ifndef _WIN32
+ if(index == 0 && path.size() > 1) {
+ return string(1, DIR_SEP);
+ }
+#endif
+ return path.substr(0, index);
+ }
+ return "";
}
string path_join(const string& dir, const string& file)
{
- return from_boost((to_boost(dir) / to_boost(file)));
+ if(dir.size() == 0) {
+ return file;
+ }
+ if(file.size() == 0) {
+ return dir;
+ }
+ string result = dir;
+#ifndef _WIN32
+ if(result[result.size() - 1] != DIR_SEP &&
+ file[0] != DIR_SEP)
+#else
+ if(result[result.size() - 1] != DIR_SEP &&
+ result[result.size() - 1] != DIR_SEP_ALT &&
+ file[0] != DIR_SEP &&
+ file[0] != DIR_SEP_ALT)
+#endif
+ {
+ result += DIR_SEP;
+ }
+ result += file;
+ return result;
}
string path_escape(const string& path)
{
string result = path;
- boost::replace_all(result, " ", "\\ ");
+ string_replace(result, " ", "\\ ");
return result;
}
bool path_is_relative(const string& path)
{
- return to_boost(path).is_relative();
+#ifdef _WIN32
+# ifdef HAVE_SHLWAPI_H
+ return PathIsRelative(path.c_str());
+# else /* HAVE_SHLWAPI_H */
+ if(path.size() >= 3) {
+ return !(((path[0] >= 'a' && path[0] <= 'z') ||
+ (path[0] >= 'A' && path[0] <= 'Z')) &&
+ path[1] == ':' && path[2] == DIR_SEP);
+ }
+ return true;
+# endif /* HAVE_SHLWAPI_H */
+#else /* _WIN32 */
+ if(path.size() == 0) {
+ return 1;
+ }
+ return path[0] != DIR_SEP;
+#endif /* _WIN32 */
+}
+
+#ifdef _WIN32
+/* Add a slash if the UNC path points to a share. */
+static string path_unc_add_slash_to_share(const string& path)
+{
+ size_t slash_after_server = path.find(DIR_SEP, 2);
+ if(slash_after_server != string::npos) {
+ size_t slash_after_share = path.find(DIR_SEP,
+ slash_after_server + 1);
+ if(slash_after_share == string::npos) {
+ return path + DIR_SEP;
+ }
+ }
+ return path;
+}
+
+/* Convert:
+ * \\?\UNC\server\share\folder\... to \\server\share\folder\...
+ * \\?\C:\ to C:\ and \\?\C:\folder\... to C:\folder\...
+ */
+static string path_unc_to_short(const string& path)
+{
+ size_t len = path.size();
+ if((len > 3) &&
+ (path[0] == DIR_SEP) &&
+ (path[1] == DIR_SEP) &&
+ (path[2] == '?') &&
+ ((path[3] == DIR_SEP) || (path[3] == DIR_SEP_ALT)))
+ {
+ if((len > 5) && (path[5] == ':')) {
+ return path.substr(4, len - 4);
+ }
+ else if ((len > 7) &&
+ (path.substr(4, 3) == "UNC") &&
+ ((path[7] == DIR_SEP) || (path[7] == DIR_SEP_ALT)))
+ {
+ return "\\\\" + path.substr(8, len - 8);
+ }
+ }
+ return path;
+}
+
+static string path_cleanup_unc(const string& path)
+{
+ string result = path_unc_to_short(path);
+ if(path.size() > 2) {
+ /* It's possible path is now a non-UNC. */
+ if(result[0] == DIR_SEP && result[1] == DIR_SEP) {
+ return path_unc_add_slash_to_share(result);
+ }
+ }
+ return result;
+}
+
+/* Make path compatible for stat() functions. */
+static string path_make_compatible(const string& path)
+{
+ string result = path;
+ /* in Windows stat() doesn't recognize dir ending on a slash. */
+ if(result.size() > 3 && result[result.size() - 1] == DIR_SEP) {
+ result.pop_back();
+ }
+ /* Clean up UNC path. */
+ if((path.size() >= 3) && (path[0] == DIR_SEP) && (path[1] == DIR_SEP)) {
+ result = path_cleanup_unc(result);
+ }
+ /* Make sure volume-only path ends up wit ha directory separator. */
+ if(result.size() == 2 && result[1] == ':') {
+ result += DIR_SEP;
+ }
+ return result;
+}
+
+static int path_wstat(const wstring& path_wc, path_stat_t *st)
+{
+#if defined(_MSC_VER) || defined(__MINGW64__)
+ return _wstat64(path_wc.c_str(), st);
+#elif defined(__MINGW32__)
+ return _wstati64(path_wc.c_str(), st);
+#else
+ return _wstat(path_wc.c_str(), st);
+#endif
+}
+
+static int path_stat(const string& path, path_stat_t *st)
+{
+ wstring path_wc = string_to_wstring(path);
+ return path_wstat(path_wc, st);
+}
+#else /* _WIN32 */
+static int path_stat(const string& path, path_stat_t *st)
+{
+ return stat(path.c_str(), st);
+}
+#endif /* _WIN32 */
+
+size_t path_file_size(const string& path)
+{
+ path_stat_t st;
+ if(path_stat(path, &st) != 0) {
+ return -1;
+ }
+ return st.st_size;
}
bool path_exists(const string& path)
{
- return boost::filesystem::exists(to_boost(path));
+#ifdef _WIN32
+ string fixed_path = path_make_compatible(path);
+ wstring path_wc = string_to_wstring(fixed_path);
+ path_stat_t st;
+ if(path_wstat(path_wc, &st) != 0) {
+ return false;
+ }
+ return st.st_mode != 0;
+#else /* _WIN32 */
+ struct stat st;
+ if(stat(path.c_str(), &st) != 0) {
+ return 0;
+ }
+ return st.st_mode != 0;
+#endif /* _WIN32 */
}
-static void path_files_md5_hash_recursive(MD5Hash& hash, const string& dir)
+bool path_is_directory(const string& path)
{
- boost::filesystem::path dirpath = to_boost(dir);
+ path_stat_t st;
+ if(path_stat(path, &st) != 0) {
+ return false;
+ }
+ return S_ISDIR(st.st_mode);
+}
- if(boost::filesystem::exists(dirpath)) {
- boost::filesystem::directory_iterator it(dirpath), it_end;
+static void path_files_md5_hash_recursive(MD5Hash& hash, const string& dir)
+{
+ if(path_exists(dir)) {
+ directory_iterator it(dir), it_end;
- for(; it != it_end; it++) {
- if(boost::filesystem::is_directory(it->status())) {
- path_files_md5_hash_recursive(hash, from_boost(it->path()));
+ for(; it != it_end; ++it) {
+ if(path_is_directory(it->path())) {
+ path_files_md5_hash_recursive(hash, it->path());
}
else {
- string filepath = from_boost(it->path());
+ string filepath = it->path();
hash.append((const uint8_t*)filepath.c_str(), filepath.size());
hash.append_file(filepath);
@@ -151,9 +608,31 @@ string path_files_md5_hash(const string& dir)
return hash.get_hex();
}
-void path_create_directories(const string& path)
+static bool create_directories_recursivey(const string& path)
{
- boost::filesystem::create_directories(to_boost(path_dirname(path)));
+ if(path_is_directory(path)) {
+ /* Directory already exists, nothing to do. */
+ return true;
+ }
+ if(path_exists(path)) {
+ /* File exists and it's not a directory. */
+ return false;
+ }
+
+ string parent = path_dirname(path);
+ if(parent.size() > 0 && parent != path) {
+ if(!create_directories_recursivey(parent)) {
+ return false;
+ }
+ }
+
+ return mkdir(path.c_str(), 0777) == 0;
+}
+
+void path_create_directories(const string& filepath)
+{
+ string path = path_dirname(filepath);
+ create_directories_recursivey(path);
}
bool path_write_binary(const string& path, const vector<uint8_t>& binary)
@@ -184,13 +663,15 @@ bool path_write_text(const string& path, string& text)
bool path_read_binary(const string& path, vector<uint8_t>& binary)
{
- binary.resize(boost::filesystem::file_size(to_boost(path)));
-
/* read binary file into memory */
FILE *f = path_fopen(path, "rb");
- if(!f)
+ if(!f) {
+ binary.resize(0);
return false;
+ }
+
+ binary.resize(path_file_size(path));
if(binary.size() == 0) {
fclose(f);
@@ -223,12 +704,18 @@ bool path_read_text(const string& path, string& text)
uint64_t path_modified_time(const string& path)
{
- if(boost::filesystem::exists(to_boost(path)))
- return (uint64_t)boost::filesystem::last_write_time(to_boost(path));
-
+ path_stat_t st;
+ if(path_stat(path, &st) != 0) {
+ return st.st_mtime;
+ }
return 0;
}
+bool path_remove(const string& path)
+{
+ return remove(path.c_str()) == 0;
+}
+
string path_source_replace_includes(const string& source_, const string& path)
{
/* our own little c preprocessor that replaces #includes with the file
@@ -265,15 +752,15 @@ void path_cache_clear_except(const string& name, const set<string>& except)
{
string dir = path_user_get("cache");
- if(boost::filesystem::exists(dir)) {
- boost::filesystem::directory_iterator it(dir), it_end;
+ if(path_exists(dir)) {
+ directory_iterator it(dir), it_end;
- for(; it != it_end; it++) {
- string filename = from_boost(it->path().filename().string());
+ for(; it != it_end; ++it) {
+ string filename = path_filename(it->path());
- if(boost::starts_with(filename, name))
+ if(string_startswith(filename, name.c_str()))
if(except.find(filename) == except.end())
- boost::filesystem::remove(to_boost(filename));
+ path_remove(it->path());
}
}
diff --git a/intern/cycles/util/util_path.h b/intern/cycles/util/util_path.h
index b81d71d1c0f..c80247f3837 100644
--- a/intern/cycles/util/util_path.h
+++ b/intern/cycles/util/util_path.h
@@ -44,7 +44,9 @@ string path_escape(const string& path);
bool path_is_relative(const string& path);
/* file info */
+size_t path_file_size(const string& path);
bool path_exists(const string& path);
+bool path_is_directory(const string& path);
string path_files_md5_hash(const string& dir);
uint64_t path_modified_time(const string& path);
@@ -59,6 +61,9 @@ bool path_write_text(const string& path, string& text);
bool path_read_binary(const string& path, vector<uint8_t>& binary);
bool path_read_text(const string& path, string& text);
+/* File manipulation. */
+bool path_remove(const string& path);
+
/* source code utility */
string path_source_replace_includes(const string& source, const string& path);
diff --git a/intern/cycles/util/util_set.h b/intern/cycles/util/util_set.h
index c568d60c4bf..c19fa071b37 100644
--- a/intern/cycles/util/util_set.h
+++ b/intern/cycles/util/util_set.h
@@ -21,7 +21,20 @@
#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
# include <unordered_set>
#else
-# include <boost/tr1/unordered_set.hpp>
+# if defined(CYCLES_TR1_UNORDERED_MAP)
+# include <tr1/unordered_set>
+# endif
+# if defined(CYCLES_STD_UNORDERED_MAP) || \
+ defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
+# include <unordered_set>
+# endif
+# if !defined(CYCLES_NO_UNORDERED_MAP) && \
+ !defined(CYCLES_TR1_UNORDERED_MAP) && \
+ !defined(CYCLES_STD_UNORDERED_MAP) && \
+ !defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
+# error One of: CYCLES_NO_UNORDERED_MAP, CYCLES_TR1_UNORDERED_MAP,\
+ CYCLES_STD_UNORDERED_MAP, CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE must be defined! // NOLINT
+# endif
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1900)
@@ -34,7 +47,15 @@ using std::set;
#if (__cplusplus > 199711L) || (defined(_MSC_VER) && _MSC_VER >= 1800)
using std::unordered_set;
#else
+# if defined(CYCLES_NO_UNORDERED_MAP)
+typedef std::set unordered_set;
+# endif
+# if defined(CYCLES_TR1_UNORDERED_MAP) || defined(CYCLES_STD_UNORDERED_MAP_IN_TR1_NAMESPACE)
using std::tr1::unordered_set;
+# endif
+# if defined(CYCLES_STD_UNORDERED_MAP)
+using std::unordered_set;
+# endif
#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_string.cpp b/intern/cycles/util/util_string.cpp
index 17235283d68..d2c1ebe4151 100644
--- a/intern/cycles/util/util_string.cpp
+++ b/intern/cycles/util/util_string.cpp
@@ -17,16 +17,15 @@
#include <stdarg.h>
#include <stdio.h>
-#include <boost/algorithm/string.hpp>
-
#include "util_foreach.h"
#include "util_string.h"
+#include "util_windows.h"
#ifdef _WIN32
-#ifndef vsnprintf
-#define vsnprintf _vsnprintf
-#endif
-#endif
+# ifndef vsnprintf
+# define vsnprintf _vsnprintf
+# endif
+#endif /* _WIN32 */
CCL_NAMESPACE_BEGIN
@@ -77,13 +76,42 @@ bool string_iequals(const string& a, const string& b)
void string_split(vector<string>& tokens, const string& str, const string& separators)
{
- vector<string> split;
+ size_t token_start = 0, token_length = 0;
+ for(size_t i = 0; i < str.size(); ++i) {
+ const char ch = str[i];
+ if(separators.find(ch) == string::npos) {
+ /* Current character is not a separator,
+ * append it to token by increasing token length.
+ */
+ ++token_length;
+ }
+ else {
+ /* Current character is a separator,
+ * append current token to the list (if token is not empty).
+ */
+ if(token_length > 0) {
+ string token = str.substr(token_start, token_length);
+ tokens.push_back(token);
+ }
+ token_start = i + 1;
+ token_length = 0;
+ }
+ }
+ /* Append token from the tail of the string if exists. */
+ if(token_length) {
+ string token = str.substr(token_start, token_length);
+ tokens.push_back(token);
+ }
+}
- boost::split(split, str, boost::is_any_of(separators), boost::token_compress_on);
+bool string_startswith(const string& s, const char *start)
+{
+ size_t len = strlen(start);
- foreach(const string& token, split)
- if(token != "")
- tokens.push_back(token);
+ if(len > s.size())
+ return 0;
+ else
+ return strncmp(s.c_str(), start, len) == 0;
}
bool string_endswith(const string& s, const char *end)
@@ -107,10 +135,11 @@ string string_strip(const string& s)
void string_replace(string& haystack, const string& needle, const string& other)
{
- size_t i;
-
- while((i = haystack.find(needle)) != string::npos)
- haystack.replace(i, needle.length(), other);
+ size_t i = 0, index;
+ while((index = haystack.find(needle, i)) != string::npos) {
+ haystack.replace(index, needle.size(), other);
+ i = index + other.size();
+ }
}
string string_remove_trademark(const string &s)
@@ -130,5 +159,49 @@ string string_from_bool(bool var)
return "False";
}
+/* Wide char strings helpers for Windows. */
+
+#ifdef _WIN32
+
+wstring string_to_wstring(const string& str)
+{
+ const int length_wc = MultiByteToWideChar(CP_ACP,
+ 0,
+ str.c_str(),
+ str.length(),
+ NULL,
+ 0);
+ wstring str_wc(length_wc + 1, 0);
+ MultiByteToWideChar(CP_ACP,
+ 0,
+ str.c_str(),
+ str.length(),
+ &str_wc[0],
+ length_wc);
+ return str_wc;
+}
+
+string string_from_wstring(const wstring& str)
+{
+ int length_mb = WideCharToMultiByte(CP_ACP,
+ 0,
+ str.c_str(),
+ str.size(),
+ NULL,
+ 0,
+ NULL, NULL);
+ string str_mb(length_mb + 1, 0);
+ WideCharToMultiByte(CP_ACP,
+ 0,
+ str.c_str(),
+ str.size(),
+ &str_mb[0],
+ length_mb,
+ NULL, NULL);
+ return str_mb;
+}
+
+#endif /* _WIN32 */
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/util/util_string.h b/intern/cycles/util/util_string.h
index b863368ab22..d73ab15d784 100644
--- a/intern/cycles/util/util_string.h
+++ b/intern/cycles/util/util_string.h
@@ -41,11 +41,22 @@ string string_printf(const char *format, ...) PRINTF_ATTRIBUTE;
bool string_iequals(const string& a, const string& b);
void string_split(vector<string>& tokens, const string& str, const string& separators = "\t ");
void string_replace(string& haystack, const string& needle, const string& other);
+bool string_startswith(const string& s, const char *start);
bool string_endswith(const string& s, const char *end);
string string_strip(const string& s);
string string_remove_trademark(const string& s);
string string_from_bool(const bool var);
+/* Wide char strings are only used on Windows to deal with non-ascii
+ * characters in file names and such. No reason to use such strings
+ * for something else at this moment.
+ */
+#ifdef _WIN32
+using std::wstring;
+wstring string_to_wstring(const string& path);
+string string_from_wstring(const wstring& path);
+#endif
+
CCL_NAMESPACE_END
#endif /* __UTIL_STRING_H__ */
diff --git a/intern/cycles/util/util_system.cpp b/intern/cycles/util/util_system.cpp
index 660c3e0c890..4ff0ee91d73 100644
--- a/intern/cycles/util/util_system.cpp
+++ b/intern/cycles/util/util_system.cpp
@@ -20,15 +20,15 @@
#include "util_string.h"
#ifdef _WIN32
-#if(!defined(FREE_WINDOWS))
-#include <intrin.h>
-#endif
-#include <windows.h>
+# if(!defined(FREE_WINDOWS))
+# include <intrin.h>
+# endif
+# include "util_windows.h"
#elif defined(__APPLE__)
-#include <sys/sysctl.h>
-#include <sys/types.h>
+# include <sys/sysctl.h>
+# include <sys/types.h>
#else
-#include <unistd.h>
+# include <unistd.h>
#endif
CCL_NAMESPACE_BEGIN
diff --git a/intern/cycles/util/util_time.cpp b/intern/cycles/util/util_time.cpp
index 964f9f1a7af..59c963cfafb 100644
--- a/intern/cycles/util/util_time.cpp
+++ b/intern/cycles/util/util_time.cpp
@@ -17,11 +17,10 @@
#include <stdlib.h>
#include "util_time.h"
+#include "util_windows.h"
#ifdef _WIN32
-#include <windows.h>
-
CCL_NAMESPACE_BEGIN
double time_dt()
diff --git a/intern/cycles/util/util_windows.h b/intern/cycles/util/util_windows.h
new file mode 100644
index 00000000000..f67e34d0f31
--- /dev/null
+++ b/intern/cycles/util/util_windows.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2011-2016 Blender Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __UTIL_WINDOWS_H__
+#define __UTIL_WINDOWS_H__
+
+#ifdef _WIN32
+
+#ifndef NOGDI
+# define NOGDI
+#endif
+#ifndef NOMINMAX
+# define NOMINMAX
+#endif
+#ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+#endif
+
+#include <windows.h>
+
+#endif /* WIN32 */
+
+#endif /* __UTIL_WINDOWS_H__ */
+