#ifdef NEED_STRING_FIXES #include #include #include #include #include namespace std { template inline std::string to_string(T value) { std::ostringstream os ; os << value ; return os.str() ; } inline int stoi( const std::string& str, std::size_t* pos = 0, int base = 10 ) { const char* begin = str.c_str() ; char* end = nullptr ; long value = std::strtol( begin, &end, base ) ; if( errno == ERANGE || value > std::numeric_limits::max() ) throw std::out_of_range( "stoi: out ofrange" ) ; if( end == str.c_str() ) throw std::invalid_argument( "stoi: invalid argument" ) ; if(pos) *pos = end - begin ; return value ; } } #endif #ifdef NEED_THREAD_FIXES #ifndef WIN32STDTHREAD_H #define WIN32STDTHREAD_H #include #include #include #include #include #include #define _STD_THREAD_INVALID_HANDLE 0 namespace std { class thread { public: class id { DWORD mId; void clear() {mId = 0;} friend class thread; public: id(DWORD aId=0):mId(aId){} bool operator==(const id& other) const {return mId == other.mId;} }; protected: HANDLE mHandle; id mThreadId; public: typedef HANDLE native_handle_type; id get_id() const noexcept {return mThreadId;} native_handle_type native_handle() const {return mHandle;} thread(): mHandle(_STD_THREAD_INVALID_HANDLE){} thread(thread& other) :mHandle(other.mHandle), mThreadId(other.mThreadId) { other.mHandle = _STD_THREAD_INVALID_HANDLE; other.mThreadId.clear(); } template explicit thread(Function&& f, Args&&... args) { typedef decltype(std::bind(f, args...)) Call; Call* call = new Call(std::bind(f, args...)); mHandle = (HANDLE)_beginthreadex(NULL, 0, threadfunc, (LPVOID)call, 0, (unsigned*)&(mThreadId.mId)); } template static unsigned int __stdcall threadfunc(void* arg) { std::unique_ptr upCall(static_cast(arg)); (*upCall)(); return (unsigned long)0; } bool joinable() const {return mHandle != _STD_THREAD_INVALID_HANDLE;} void join() { if (get_id() == GetCurrentThreadId()) throw system_error(EDEADLK, generic_category()); if (mHandle == _STD_THREAD_INVALID_HANDLE) throw system_error(ESRCH, generic_category()); if (!joinable()) throw system_error(EINVAL, generic_category()); WaitForSingleObject(mHandle, INFINITE); CloseHandle(mHandle); mHandle = _STD_THREAD_INVALID_HANDLE; mThreadId.clear(); } ~thread() { if (joinable()) std::terminate(); } thread& operator=(const thread&) = delete; thread& operator=(thread&& other) noexcept { if (joinable()) std::terminate(); swap(std::forward(other)); return *this; } void swap(thread&& other) noexcept { std::swap(mHandle, other.mHandle); std::swap(mThreadId.mId, other.mThreadId.mId); } static unsigned int hardware_concurrency() noexcept {return 1;} void detach() { if (!joinable()) throw system_error(); mHandle = _STD_THREAD_INVALID_HANDLE; mThreadId.clear(); } }; namespace this_thread { inline thread::id get_id() {return thread::id(GetCurrentThreadId());} inline void yield() {Sleep(0);} template< class Rep, class Period > void sleep_for( const std::chrono::duration& sleep_duration) { Sleep(chrono::duration_cast(sleep_duration).count()); } template void sleep_until(const std::chrono::time_point& sleep_time) { sleep_for(sleep_time-Clock::now()); } } } #endif #endif