diff --git a/CMakeLists.txt b/CMakeLists.txt index 1307a775a..9fa2630d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,8 @@ project ("LTP - Language Technology Platform") set (CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) if (APPLE) - set(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libstdc++ -Wno-error=c++11-narrowing") + add_definitions(-DGTEST_HAS_TR1_TUPLE=0) + set(CMAKE_CXX_FLAGS "-std=c++11 -Wno-c++11-narrowing") endif(APPLE) if (MINGW) diff --git a/doc/ltp-document-3.0.md b/doc/ltp-document-3.0.md index 390d6b6df..37f3c71bf 100644 --- a/doc/ltp-document-3.0.md +++ b/doc/ltp-document-3.0.md @@ -87,7 +87,6 @@ Linux、Mac OSX(*)和Cygwin的用户,可以直接在项目根目录下使用 ./configure make -(注:Mac OSX如果要编译example下的示例程序,请加入-std=c++11 -stdlib=libstdc++ -Wno-error=c++11-narrowing选项) 进行编译。 diff --git a/src/utils/cfgparser.hpp b/src/utils/cfgparser.hpp index d07ba4438..f426036c0 100644 --- a/src/utils/cfgparser.hpp +++ b/src/utils/cfgparser.hpp @@ -20,15 +20,14 @@ class ConfigParser { bool _valid; #if defined(_MSC_VER) - typedef stdext::hash_map internal_entries_t; - typedef stdext::hash_map internal_sections_t; + typedef std::unordered_map internal_entries_t; + typedef std::unordered_map internal_sections_t; #else - typedef std::tr1::unordered_map internal_entries_t; - typedef std::tr1::unordered_map internal_sections_t; #endif // end for _WIN32 - internal_sections_t sec; public: diff --git a/src/utils/chartypes.hpp b/src/utils/chartypes.hpp index 5e0bcdc85..b131c2d7b 100644 --- a/src/utils/chartypes.hpp +++ b/src/utils/chartypes.hpp @@ -84,10 +84,10 @@ class __chartype_collections { private: #if defined(_MSC_VER) - typedef stdext::hash_map internal_collection_t; #else - typedef std::tr1::unordered_map internal_collection_t; #endif // end for _WIN32 diff --git a/src/utils/math/sparsevec.h b/src/utils/math/sparsevec.h index eeb1dbc15..561db4dff 100644 --- a/src/utils/math/sparsevec.h +++ b/src/utils/math/sparsevec.h @@ -11,10 +11,11 @@ namespace math { class SparseVec { public: + #if defined(_MSC_VER) - typedef stdext::hash_map internal_sparsevec_t; + typedef std::unordered_map internal_sparsevec_t; #else - typedef std::tr1::unordered_map internal_sparsevec_t; + typedef std::unordered_map internal_sparsevec_t; // typedef __gnu_cxx::hash_map internal_sparsevec_t; #endif // end for _WIN32 typedef internal_sparsevec_t::iterator iterator; diff --git a/src/utils/stringmap.hpp b/src/utils/stringmap.hpp index 5dfbd6217..4d9b0a4d9 100644 --- a/src/utils/stringmap.hpp +++ b/src/utils/stringmap.hpp @@ -21,6 +21,7 @@ namespace utility { template class StringMap { public: +/* #if defined(_MSC_VER) typedef stdext::hash_map internal_map_t; @@ -29,7 +30,8 @@ class StringMap { __Default_CharArray_HashFunction, __Default_CharArray_EqualFunction> internal_map_t; #endif // end for _WIN32 - +*/ + typedef std::unordered_map internal_map_t; typedef typename internal_map_t::iterator iterator; typedef typename internal_map_t::const_iterator const_iterator; diff --git a/src/utils/template.hpp b/src/utils/template.hpp index c73a7f12e..6318b292c 100644 --- a/src/utils/template.hpp +++ b/src/utils/template.hpp @@ -22,14 +22,13 @@ template class __Template_Token_Cache { private: #if defined(_MSC_VER) - typedef stdext::hash_map indexing_t; #else - typedef std::tr1::unordered_map indexing_t; #endif // end for _WIN32 - public: /** * The entry function for the singleton. It's a typical get_instance diff --git a/src/utils/unordered_map.hpp b/src/utils/unordered_map.hpp index 65c76027c..d78917d0e 100644 --- a/src/utils/unordered_map.hpp +++ b/src/utils/unordered_map.hpp @@ -1,11 +1,105 @@ // Portable STL hashmap include file. #ifndef __UTILS_UNORDERED_MAP_HPP__ #define __UTILS_UNORDERED_MAP_HPP__ +// Portable header for std::unordered_map template. Welcome to C++. Enjoy! +// - rlyeh / BOOST licensed +/* + * Just in case somebody else defined `unordered_map` before us. + */ + +#ifdef unordered_map +#undef unordered_map +#endif + +/* Headers (in order) + * - std >= C++11: GCC <4.7.X defines __cplusplus as 1, use __GXX_EXPERIMENTAL_CXX0X__ instead + * - ICC + * - G++ >= 4.3.X + * - G++ >= 3.X.X + * - MSVC++ >= 9.0 + * - OTHERS + */ + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +#include +#elif defined(__INTEL_COMPILER) +#include +#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3) +#include +#elif defined(__GNUC__) && __GNUC__ >= 3 +#include +#elif defined(_MSC_VER) && ( ( _MSC_VER >= 1500 && _HAS_TR1 ) || ( _MSC_VER >= 1600 ) ) +#include +#else +#include +#endif + +/* Namespace and type (in order) + * - C++11, C++0X (std::unordered_map) + * - STLPORT (std::hash_map) + * - MSVC++ 2010 (std::unordered_map) + * - MSVC++ 9.0 (std::tr1::unordered_map) + * - MSVC++ 7.0 (stdext::hash_map) + * - G++ 4.3.X (std::tr1::unordered_map) + * - G++ 3.X.X, ICC (__gnu_cxx::hash_map) + * - OTHERS (std::hash_map) + */ + +#if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) +// ok + +#elif defined(_STLPORT_VERSION) +#define unordered_map hash_map +namespace std { using std::hash_map; } + +#elif defined(_MSC_VER) && _MSC_VER >= 1600 +// ok + +#elif defined(_MSC_VER) && _MSC_VER >= 1500 && _HAS_TR1 +namespace std { using std::tr1::unordered_map; } + +#elif defined(_MSC_VER) && _MSC_VER >= 1300 +#define unordered_map hash_map +namespace std { using stdext::hash_map; } + +#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ >= 3) +namespace std { using std::tr1::unordered_map; } + +#elif (defined(__GNUC__) && __GNUC__ >= 3) || defined(__INTEL_COMPILER) +#include +#define unordered_map hash_map +namespace std { using __gnu_cxx::hash_map; } + + namespace __gnu_cxx { + template<> struct hash { + size_t operator()(const unsigned long long &__x) const { + return (size_t)__x; + } + }; + template struct hash { + size_t operator()(T * const &__x) const { + return (size_t)__x; + } + }; + template<> struct hash { + size_t operator()(const std::string &__x) const { + return hash()(__x.c_str()); + } + }; + }; + +#else +#define unordered_map hash_map +namespace std { using std::hash_map; } + +#endif + +/* #if defined(_MSC_VER) #include #else #include #endif - +*/ #endif // end for __UTILS_UNORDERED_MAP_HPP__ diff --git a/test/multi_cws_cmdline.cpp b/test/multi_cws_cmdline.cpp index 8ecc13a26..58d9c7ec5 100644 --- a/test/multi_cws_cmdline.cpp +++ b/test/multi_cws_cmdline.cpp @@ -24,8 +24,8 @@ #include "tinythread.h" #include "segment_dll.h" -using namespace std; -using namespace tthread; +//using namespace std; +//using namespace tthread; const int MAX_LEN = 1024; @@ -35,20 +35,20 @@ class Dispatcher { _model = model; } - int next(string &sentence) { + int next(std::string &sentence) { sentence = ""; - lock_guard guard(_mutex); - if (!getline(cin, sentence, '\n')) { + tthread::lock_guard guard(_mutex); + if (!getline(std::cin, sentence, '\n')) { return -1; } return 0; } - void output(const vector &result) { - lock_guard guard(_mutex); + void output(const std::vector &result) { + tthread::lock_guard guard(_mutex); for (int i = 0; i < result.size(); ++ i) { - cout << result[i]; - cout << (i == result.size() - 1 ? '\n' : '\t'); + std::cout << result[i]; + std::cout << (i == result.size() - 1 ? '\n' : '\t'); } return; } @@ -58,14 +58,14 @@ class Dispatcher { } private: - mutex _mutex; + tthread::mutex _mutex; void * _model; - string _sentence; + std::string _sentence; }; void multithreaded_segment( void * args) { - string sentence; - vector result; + std::string sentence; + std::vector result; Dispatcher * dispatcher = (Dispatcher *)args; void * model = dispatcher->model(); @@ -108,8 +108,8 @@ int main(int argc, char ** argv) { return -1; } - if(num_threads < 0 || num_threads > thread::hardware_concurrency()) { - num_threads = thread::hardware_concurrency(); + if(num_threads < 0 || num_threads > tthread::thread::hardware_concurrency()) { + num_threads = tthread::thread::hardware_concurrency(); } std::cerr << "TRACE: Model is loaded" << std::endl; @@ -118,15 +118,15 @@ int main(int argc, char ** argv) { Dispatcher* dispatcher = new Dispatcher( engine ); double tm = ltp::utility::get_time(); - list thread_list; + std::list thread_list; for (int i = 0; i < num_threads; ++ i) { - thread* t = new thread( multithreaded_segment, (void *)dispatcher ); + tthread::thread* t = new tthread::thread( multithreaded_segment, (void *)dispatcher ); thread_list.push_back( t ); } - for (list::iterator i = thread_list.begin(); + for (std::list::iterator i = thread_list.begin(); i != thread_list.end(); ++ i) { - thread * t = *i; + tthread::thread * t = *i; t->join(); delete t; } diff --git a/test/multi_ltp_test.cpp b/test/multi_ltp_test.cpp index ea0ac618e..2f33efb41 100644 --- a/test/multi_ltp_test.cpp +++ b/test/multi_ltp_test.cpp @@ -19,10 +19,10 @@ #include "time.hpp" #include "Ltp.h" -using namespace std; -using namespace tthread; +//using namespace std; +//using namespace tthread; -string type; +std::string type; class Dispatcher { public: @@ -32,17 +32,17 @@ class Dispatcher { _idx(0), _ifs(ifs) {} - int next(string &sentence) { + int next(std::string &sentence) { sentence = ""; - lock_guard guard(_mutex); + tthread::lock_guard guard(_mutex); if (!getline(_ifs, sentence, '\n')) { return -1; } return _max_idx ++; } - void output(int idx, const string &result) { - lock_guard guard(_mutex); + void output(int idx, const std::string &result) { + tthread::lock_guard guard(_mutex); if (idx > _idx) { _back[idx] = result; @@ -69,7 +69,7 @@ class Dispatcher { } private: - mutex _mutex; + tthread::mutex _mutex; LTP * _engine; int _max_idx; int _idx; @@ -79,7 +79,7 @@ class Dispatcher { }; void multithreaded_ltp( void * args) { - string sentence; + std::string sentence; Dispatcher * dispatcher = (Dispatcher *)args; LTP * engine = dispatcher->get_engine(); @@ -109,7 +109,7 @@ void multithreaded_ltp( void * args) { engine->srl(xml4nlp); } - string result; + std::string result; // for segmentation only if (type == "sp") @@ -148,7 +148,7 @@ void multithreaded_ltp( void * args) { int main(int argc, char ** argv) { if (argc != 4) { - cerr << "Usage: ./ltp_test " << endl; + std::cerr << "Usage: ./ltp_test " << endl; exit(1); } @@ -163,20 +163,20 @@ int main(int argc, char ** argv) { type = _type; Dispatcher * dispatcher = new Dispatcher( &engine, ifs); - int num_threads = thread::hardware_concurrency(); + int num_threads = tthread::thread::hardware_concurrency(); std::cerr << "TRACE: LTP is built" << std::endl; std::cerr << "TRACE: Running " << num_threads << " thread(s)" << std::endl; double tm = ltp::utility::get_time(); - list thread_list; + std::list thread_list; for (int i = 0; i < num_threads; ++ i) { - thread * t = new thread(multithreaded_ltp, (void *)dispatcher ); + tthread::thread * t = new tthread::thread(multithreaded_ltp, (void *)dispatcher ); thread_list.push_back( t ); } - for (list::iterator i = thread_list.begin(); + for (std::list::iterator i = thread_list.begin(); i != thread_list.end(); ++ i) { - thread * t = *i; + tthread::thread * t = *i; t->join(); delete t; } diff --git a/test/multi_pos_cmdline.cpp b/test/multi_pos_cmdline.cpp index da0cbdd60..cfed31c08 100644 --- a/test/multi_pos_cmdline.cpp +++ b/test/multi_pos_cmdline.cpp @@ -21,8 +21,8 @@ #include "tinythread.h" #include "postag_dll.h" -using namespace std; -using namespace tthread; +//using namespace std; +//using namespace tthread; const int MAX_LEN = 1024; @@ -35,7 +35,7 @@ class Dispatcher { int next(std::vector &words) { std::string line; std::string word; - lock_guard guard(_mutex); + tthread::lock_guard guard(_mutex); if (getline(std::cin, line, '\n')) { std::stringstream S(line); words.clear(); @@ -48,7 +48,7 @@ class Dispatcher { void output(const std::vector & words, const std::vector &postags) { - lock_guard guard(_mutex); + tthread::lock_guard guard(_mutex); if (words.size() != postags.size()) { return; } @@ -65,9 +65,9 @@ class Dispatcher { } private: - mutex _mutex; + tthread::mutex _mutex; void * _model; - string _sentence; + std::string _sentence; }; void multithreaded_postag( void * args) { @@ -108,8 +108,8 @@ int main(int argc, char ** argv) { int num_threads = atoi(argv[2]); - if(num_threads < 0 || num_threads > thread::hardware_concurrency()) { - num_threads = thread::hardware_concurrency(); + if(num_threads < 0 || num_threads > tthread::thread::hardware_concurrency()) { + num_threads = tthread::thread::hardware_concurrency(); } std::cerr << "TRACE: Model is loaded" << std::endl; @@ -118,15 +118,15 @@ int main(int argc, char ** argv) { Dispatcher * dispatcher = new Dispatcher( engine ); double tm = ltp::utility::get_time(); - list thread_list; + std::list thread_list; for (int i = 0; i < num_threads; ++ i) { - thread * t = new thread( multithreaded_postag, (void *)dispatcher ); + tthread::thread * t = new tthread::thread( multithreaded_postag, (void *)dispatcher ); thread_list.push_back( t ); } - for (list::iterator i = thread_list.begin(); + for (std::list::iterator i = thread_list.begin(); i != thread_list.end(); ++ i) { - thread * t = *i; + tthread::thread * t = *i; t->join(); delete t; }