From ccf7d3b9b2c9ce102db538bcf8b73a197a3cb1a8 Mon Sep 17 00:00:00 2001 From: eidheim Date: Wed, 6 Jul 2016 14:53:18 +0200 Subject: [PATCH] Now compiles with c++14 instead of c++11, and some src/git.* cleanup --- CMakeLists.txt | 2 +- README.md | 2 +- src/cmake.cc | 3 +-- src/ctags.cc | 2 +- src/debug_lldb.cc | 8 ++++---- src/directories.cc | 38 +++++++++++++++----------------------- src/git.cc | 31 ++++++++++++++++++------------- src/git.h | 19 +++++++++---------- src/project.cc | 4 ++-- src/project_build.cc | 2 +- src/source_clang.cc | 6 +++--- src/source_diff.cc | 4 ++-- src/source_spellcheck.cc | 2 +- src/terminal.cc | 10 +++++----- src/tooltips.cc | 4 ++-- src/window.cc | 8 ++++---- tests/git_test.cc | 4 ++-- 17 files changed, 72 insertions(+), 77 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c2cb2e..17ae446 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required (VERSION 2.8.8) set(project_name juci) project (${project_name}) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -Wall -Wextra -Wno-unused-parameter -Wno-reorder") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++1y -pthread -Wall -Wextra -Wno-unused-parameter -Wno-reorder") if(CMAKE_BUILD_TYPE STREQUAL "") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") endif() diff --git a/README.md b/README.md index b4d7516..e36a032 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ ## About Current IDEs struggle with C++ support due to the complexity of the programming language. juCI++, however, is designed especially -towards libclang with speed and ease of use in mind. +towards libclang with speed, stability, and ease of use in mind. ## Features * Platform independent diff --git a/src/cmake.cc b/src/cmake.cc index 0374426..1259782 100644 --- a/src/cmake.cc +++ b/src/cmake.cc @@ -101,8 +101,7 @@ bool CMake::update_debug_build(const boost::filesystem::path &debug_build_path, if(!force && boost::filesystem::exists(debug_build_path/"CMakeCache.txt")) return true; - std::unique_ptr message; - message=std::unique_ptr(new Dialog::Message("Creating/updating debug build")); + auto message=std::make_unique("Creating/updating debug build"); auto exit_status=Terminal::get().process(Config::get().project.cmake_command+" "+ filesystem::escape_argument(project_path)+" -DCMAKE_BUILD_TYPE=Debug", debug_build_path); if(message) diff --git a/src/ctags.cc b/src/ctags.cc index 4c7485a..5ef7a69 100644 --- a/src/ctags.cc +++ b/src/ctags.cc @@ -37,7 +37,7 @@ std::pair > Ctags::g std::stringstream stdin_stream; //TODO: when debian stable gets newer g++ version that supports move on streams, remove unique_ptr below - std::unique_ptr stdout_stream(new std::stringstream()); + auto stdout_stream=std::make_unique(); auto command=Config::get().project.ctags_command+exclude+" --fields=ns --sort=foldcase -I \"override noexcept\" -f - -R *"; Terminal::get().process(stdin_stream, *stdout_stream, command, run_path); return {run_path, std::move(stdout_stream)}; diff --git a/src/debug_lldb.cc b/src/debug_lldb.cc index 41bfc82..6de35d7 100644 --- a/src/debug_lldb.cc +++ b/src/debug_lldb.cc @@ -45,8 +45,8 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat const std::string &remote_host) { if(!debugger) { lldb::SBDebugger::Initialize(); - debugger=std::unique_ptr(new lldb::SBDebugger(lldb::SBDebugger::Create(true, log, nullptr))); - listener=std::unique_ptr(new lldb::SBListener("juCi++ lldb listener")); + debugger=std::make_unique(lldb::SBDebugger::Create(true, log, nullptr)); + listener=std::make_unique("juCi++ lldb listener"); } //Create executable string and argument array @@ -103,7 +103,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat lldb::SBError error; if(!remote_host.empty()) { auto connect_string="connect://"+remote_host; - process = std::unique_ptr(new lldb::SBProcess(target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error))); + process = std::make_unique(target.ConnectRemote(*listener, connect_string.c_str(), "gdb-remote", error)); if(error.Fail()) { Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); if(callback) @@ -128,7 +128,7 @@ void Debug::LLDB::start(const std::string &command, const boost::filesystem::pat process->Continue(); } else - process = std::unique_ptr(new lldb::SBProcess(target.Launch(*listener, argv, const_cast(environ), nullptr, nullptr, nullptr, path.string().c_str(), lldb::eLaunchFlagNone, false, error))); + process = std::make_unique(target.Launch(*listener, argv, const_cast(environ), nullptr, nullptr, nullptr, path.string().c_str(), lldb::eLaunchFlagNone, false, error)); if(error.Fail()) { Terminal::get().async_print(std::string("Error (debug): ")+error.GetCString()+'\n', true); if(callback) diff --git a/src/directories.cc b/src/directories.cc index 0e5f389..3705a86 100644 --- a/src/directories.cc +++ b/src/directories.cc @@ -552,7 +552,7 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co std::shared_ptr repository; try { - repository=Git::get().get_repository(dir_path); + repository=Git::get_repository(dir_path); } catch(const std::exception &) {} @@ -593,22 +593,18 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co directories[dir_path.string()]={row, monitor, repository, repository_connection}; } - std::unique_ptr children; //Gtk::TreeNodeChildren is missing default constructor... - if(row) - children=std::unique_ptr(new Gtk::TreeNodeChildren(row.children())); - else - children=std::unique_ptr(new Gtk::TreeNodeChildren(tree_store->children())); - if(*children) { - if(children->begin()->get_value(column_record.path)=="") - tree_store->erase(children->begin()); + Gtk::TreeNodeChildren children(row?row.children():tree_store->children()); + if(children) { + if(children.begin()->get_value(column_record.path)=="") + tree_store->erase(children.begin()); } std::unordered_set not_deleted; boost::filesystem::directory_iterator end_it; for(boost::filesystem::directory_iterator it(dir_path);it!=end_it;it++) { auto filename=it->path().filename().string(); bool already_added=false; - if(*children) { - for(auto &child: *children) { + if(children) { + for(auto &child: children) { if(child->get_value(column_record.name)==filename) { not_deleted.emplace(filename); already_added=true; @@ -617,7 +613,7 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co } } if(!already_added) { - auto child = tree_store->append(*children); + auto child = tree_store->append(children); not_deleted.emplace(filename); child->set_value(column_record.name, filename); child->set_value(column_record.markup, Glib::Markup::escape_text(filename)); @@ -638,8 +634,8 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co } } } - if(*children) { - for(auto it=children->begin();it!=children->end();) { + if(children) { + for(auto it=children.begin();it!=children.end();) { if(not_deleted.count(it->get_value(column_record.name))==0) { it=tree_store->erase(it); } @@ -647,8 +643,8 @@ void Directories::add_or_update_path(const boost::filesystem::path &dir_path, co it++; } } - if(!*children) { - auto child=tree_store->append(*children); + if(!children) { + auto child=tree_store->append(children); child->set_value(column_record.name, std::string("(empty)")); child->set_value(column_record.markup, Glib::Markup::escape_text("(empty)")); child->set_value(column_record.type, PathType::UNKNOWN); @@ -720,15 +716,11 @@ void Directories::colorize_path(const boost::filesystem::path &dir_path_, bool i green.set_blue(normal_color.get_blue()+factor*(green.get_blue()-normal_color.get_blue())); do { - std::unique_ptr children; //Gtk::TreeNodeChildren is missing default constructor... - if(it->second.row) - children=std::unique_ptr(new Gtk::TreeNodeChildren(it->second.row.children())); - else - children=std::unique_ptr(new Gtk::TreeNodeChildren(tree_store->children())); - if(!*children) + Gtk::TreeNodeChildren children(it->second.row?it->second.row.children():tree_store->children()); + if(!children) return; - for(auto &child: *children) { + for(auto &child: children) { auto name=Glib::Markup::escape_text(child.get_value(column_record.name)); auto path=child.get_value(column_record.path); Gdk::RGBA *color; diff --git a/src/git.cc b/src/git.cc index b9fd3a3..c97ef3c 100644 --- a/src/git.cc +++ b/src/git.cc @@ -1,7 +1,9 @@ #include "git.h" #include +bool Git::initialized=false; std::mutex Git::mutex; +std::unordered_map, size_t> > Git::repositories; std::mutex Git::repositories_mutex; std::string Git::Error::message() noexcept { @@ -179,23 +181,23 @@ Git::Repository::Status Git::Repository::get_status() { Status status; bool first=true; std::unique_lock status_saved_lock(saved_status_mutex, std::defer_lock); - std::function callback=[this, &status, &first, &status_saved_lock](const char *path_cstr, Git::Repository::STATUS status_enum) { + std::function callback=[this, &status, &first, &status_saved_lock](const char *path_cstr, STATUS status_enum) { if(first) { status_saved_lock.lock(); first=false; } boost::filesystem::path rel_path(path_cstr); do { - if(status_enum==Git::Repository::STATUS::MODIFIED) + if(status_enum==STATUS::MODIFIED) status.modified.emplace((work_path/rel_path).generic_string()); - if(status_enum==Git::Repository::STATUS::NEW) + if(status_enum==STATUS::NEW) status.added.emplace((work_path/rel_path).generic_string()); rel_path=rel_path.parent_path(); } while(!rel_path.empty()); }; Error error; std::lock_guard lock(mutex); - error.code = git_status_foreach(repository.get(), Repository::status_callback, &callback); + error.code = git_status_foreach(repository.get(), status_callback, &callback); if(error) throw std::runtime_error(error.message()); saved_status=status; @@ -222,7 +224,8 @@ boost::filesystem::path Git::Repository::get_path() noexcept { return Git::path(git_repository_path(repository.get())); } -boost::filesystem::path Git::Repository::root_path(const boost::filesystem::path &path) { +boost::filesystem::path Git::Repository::get_root_path(const boost::filesystem::path &path) { + initialize(); git_buf root = {0, 0, 0}; { Error error; @@ -241,7 +244,8 @@ Git::Repository::Diff Git::Repository::get_diff(const boost::filesystem::path &p return Diff(path, repository.get()); } -Git::Git() : repositories(new std::unordered_map, size_t> >()) { +void Git::initialize() noexcept { + std::lock_guard lock(mutex); if(!initialized) { #if LIBGIT2_SOVERSION>=22 git_libgit2_init(); @@ -253,24 +257,25 @@ Git::Git() : repositories(new std::unordered_map Git::get_repository(const boost::filesystem::path &path) { + initialize(); std::lock_guard lock(repositories_mutex); - auto root_path=std::make_shared(Repository::root_path(path).generic_string()); - auto it=repositories->find(*root_path); + auto root_path=std::make_shared(Repository::get_root_path(path).generic_string()); + auto it=repositories.find(*root_path); Repository *repository_ptr; - if(it!=repositories->end()) { + if(it!=repositories.end()) { it->second.second++; repository_ptr=it->second.first.get(); } else { - it=repositories->emplace(*root_path, std::pair, size_t>(std::unique_ptr(new Repository(*root_path)), 1)).first; + it=repositories.emplace(*root_path, std::make_pair(std::unique_ptr(new Repository(*root_path)), 1)).first; repository_ptr=it->second.first.get(); } - return std::shared_ptr(repository_ptr, [this, root_path](Repository *) { + return std::shared_ptr(repository_ptr, [root_path](Repository *) { std::lock_guard lock(repositories_mutex); - auto it=repositories->find(*root_path); + auto it=repositories.find(*root_path); it->second.second--; if(it->second.second==0) - repositories->erase(it); + repositories.erase(it); }); } diff --git a/src/git.h b/src/git.h index 6b46016..a0c763b 100644 --- a/src/git.h +++ b/src/git.h @@ -11,6 +11,7 @@ #include class Git { + friend class Repository; public: class Error { friend class Git; @@ -74,7 +75,7 @@ public: boost::filesystem::path get_work_path() noexcept; boost::filesystem::path get_path() noexcept; - static boost::filesystem::path root_path(const boost::filesystem::path &path); + static boost::filesystem::path get_root_path(const boost::filesystem::path &path); Diff get_diff(const boost::filesystem::path &path); @@ -82,21 +83,19 @@ public: }; private: + static bool initialized; + ///Mutex for thread safe operations static std::mutex mutex; - bool initialized=false; - std::unordered_map, size_t> > *repositories; //Freed by OS at program exit + + static std::unordered_map, size_t> > repositories; static std::mutex repositories_mutex; - Git(); + ///Call initialize in public static methods + static void initialize() noexcept; static boost::filesystem::path path(const char *cpath, size_t cpath_length=static_cast(-1)) noexcept; - public: - static Git &get() noexcept { - static Git instance; - return instance; - } - std::shared_ptr get_repository(const boost::filesystem::path &path); + static std::shared_ptr get_repository(const boost::filesystem::path &path); }; #endif //JUCI_GIT_H_ diff --git a/src/project.cc b/src/project.cc index 6078fa5..a95cbf4 100644 --- a/src/project.cc +++ b/src/project.cc @@ -412,7 +412,7 @@ void Project::Clang::debug_backtrace() { auto backtrace=Debug::LLDB::get().get_backtrace(); auto iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); + view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(iter), true, true); auto rows=std::make_shared >(); if(backtrace.size()==0) return; @@ -462,7 +462,7 @@ void Project::Clang::debug_show_variables() { auto variables=Debug::LLDB::get().get_variables(); auto iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(iter), true, true)); + view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(iter), true, true); auto rows=std::make_shared >(); if(variables.size()==0) return; diff --git a/src/project_build.cc b/src/project_build.cc index 1739eee..afdc6ee 100644 --- a/src/project_build.cc +++ b/src/project_build.cc @@ -6,7 +6,7 @@ std::unique_ptr Project::Build::create(const boost::filesystem:: if(!cmake->project_path.empty()) return cmake; else - return std::unique_ptr(new Project::Build()); + return std::make_unique(); } boost::filesystem::path Project::Build::get_default_path() { diff --git a/src/source_clang.cc b/src/source_clang.cc index e8dc420..305d58f 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -104,7 +104,7 @@ void Source::ClangViewParse::parse_initialize() { } pos++; } - clang_tu = std::unique_ptr(new clang::TranslationUnit(clang_index, file_path.string(), get_compilation_commands(), buffer.raw())); + clang_tu = std::make_unique(clang_index, file_path.string(), get_compilation_commands(), buffer.raw()); clang_tokens=clang_tu->get_tokens(0, buffer.bytes()-1); update_syntax(); @@ -539,7 +539,7 @@ void Source::ClangViewAutocomplete::autocomplete_dialog_setup() { auto start_iter=get_buffer()->get_insert()->get_iter(); if(prefix.size()>0 && !start_iter.backward_chars(prefix.size())) return; - autocomplete_dialog=std::unique_ptr(new CompletionDialog(*this, get_buffer()->create_mark(start_iter))); + autocomplete_dialog=std::make_unique(*this, get_buffer()->create_mark(start_iter)); autocomplete_dialog_rows.clear(); autocomplete_dialog->on_hide=[this](){ get_buffer()->end_user_action(); @@ -1315,7 +1315,7 @@ void Source::ClangViewRefactor::wait_parsing(const std::vector &v if(!clang_view->parsed) { clang_views.emplace_back(clang_view); if(!message) - message=std::unique_ptr(new Dialog::Message("Please wait while all buffers finish parsing")); + message=std::make_unique("Please wait while all buffers finish parsing"); } } } diff --git a/src/source_diff.cc b/src/source_diff.cc index 2c62ea6..0b1e0c4 100644 --- a/src/source_diff.cc +++ b/src/source_diff.cc @@ -98,7 +98,7 @@ void Source::DiffView::configure() { return; try { - repository=Git::get().get_repository(this->file_path.parent_path()); + repository=Git::get_repository(this->file_path.parent_path()); } catch(const std::exception &) { return; @@ -308,7 +308,7 @@ std::unique_ptr Source::DiffView::get_diff() { if(relative_path.empty()) throw std::runtime_error("not a relative path"); } - return std::unique_ptr(new Git::Repository::Diff(repository->get_diff(relative_path))); + return std::make_unique(repository->get_diff(relative_path)); } void Source::DiffView::update_lines() { diff --git a/src/source_spellcheck.cc b/src/source_spellcheck.cc index 5f16053..b5052b2 100644 --- a/src/source_spellcheck.cc +++ b/src/source_spellcheck.cc @@ -148,7 +148,7 @@ Source::SpellCheckView::SpellCheckView() : Gsv::View() { } } if(need_suggestions) { - spellcheck_suggestions_dialog=std::unique_ptr(new SelectionDialog(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false)); + spellcheck_suggestions_dialog=std::make_unique(*this, get_buffer()->create_mark(get_buffer()->get_insert()->get_iter()), false); auto word=spellcheck_get_word(get_buffer()->get_insert()->get_iter()); auto suggestions=spellcheck_get_suggestions(word.first, word.second); if(suggestions.size()==0) diff --git a/src/terminal.cc b/src/terminal.cc index 0c8d71f..1e60ac9 100644 --- a/src/terminal.cc +++ b/src/terminal.cc @@ -59,13 +59,13 @@ Terminal::Terminal() { int Terminal::process(const std::string &command, const boost::filesystem::path &path, bool use_pipes) { std::unique_ptr process; if(use_pipes) - process=std::unique_ptr(new Process(command, path.string(), [this](const char* bytes, size_t n) { + process=std::make_unique(command, path.string(), [this](const char* bytes, size_t n) { async_print(std::string(bytes, n)); }, [this](const char* bytes, size_t n) { async_print(std::string(bytes, n), true); - })); + }); else - process=std::unique_ptr(new Process(command, path.string())); + process=std::make_unique(command, path.string()); if(process->get_id()<=0) { async_print("Error: failed to run command: " + command + "\n", true); @@ -113,11 +113,11 @@ void Terminal::async_process(const std::string &command, const boost::filesystem std::thread async_execute_thread([this, command, path, callback](){ std::unique_lock processes_lock(processes_mutex); stdin_buffer.clear(); - std::shared_ptr process(new Process(command, path.string(), [this](const char* bytes, size_t n) { + auto process=std::make_shared(command, path.string(), [this](const char* bytes, size_t n) { async_print(std::string(bytes, n)); }, [this](const char* bytes, size_t n) { async_print(std::string(bytes, n), true); - }, true)); + }, true); auto pid=process->get_id(); if (pid<=0) { processes_lock.unlock(); diff --git a/src/tooltips.cc b/src/tooltips.cc index abd4a82..a603fb2 100644 --- a/src/tooltips.cc +++ b/src/tooltips.cc @@ -46,7 +46,7 @@ void Tooltip::update() { void Tooltip::show(bool disregard_drawn) { if(!window) { //init window - window=std::unique_ptr(new Gtk::Window(Gtk::WindowType::WINDOW_POPUP)); + window=std::make_unique(Gtk::WindowType::WINDOW_POPUP); auto g_application=g_application_get_default(); auto gio_application=Glib::wrap(g_application, true); @@ -61,7 +61,7 @@ void Tooltip::show(bool disregard_drawn) { window->set_skip_taskbar_hint(true); window->set_default_size(0, 0); - tooltip_widget=std::unique_ptr(new Gtk::TextView(create_tooltip_buffer())); + tooltip_widget=std::make_unique(create_tooltip_buffer()); wrap_lines(tooltip_widget->get_buffer()); tooltip_widget->set_editable(false); auto tag=text_view.get_buffer()->get_tag_table()->lookup("def:note_background"); diff --git a/src/window.cc b/src/window.cc index c76af17..f150c9d 100644 --- a/src/window.cc +++ b/src/window.cc @@ -452,7 +452,7 @@ void Window::set_menu_actions() { stream->seekg(0, std::ios::beg); auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(dialog_iter), true, true)); + view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); std::string line; @@ -551,7 +551,7 @@ void Window::set_menu_actions() { auto locations=view->get_implementation_locations(Notebook::get().get_views()); if(!locations.empty()) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(dialog_iter), true, true)); + view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); auto project_path=Project::Build::create(view->file_path)->project_path; if(project_path.empty()) { @@ -608,7 +608,7 @@ void Window::set_menu_actions() { auto usages=view->get_usages(Notebook::get().get_views()); if(!usages.empty()) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(dialog_iter), true, true)); + view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); auto iter=view->get_buffer()->get_insert()->get_iter(); @@ -658,7 +658,7 @@ void Window::set_menu_actions() { auto methods=Notebook::get().get_current_view()->get_methods(); if(!methods.empty()) { auto dialog_iter=view->get_iter_for_dialog(); - view->selection_dialog=std::unique_ptr(new SelectionDialog(*view, view->get_buffer()->create_mark(dialog_iter), true, true)); + view->selection_dialog=std::make_unique(*view, view->get_buffer()->create_mark(dialog_iter), true, true); auto rows=std::make_shared >(); auto iter=view->get_buffer()->get_insert()->get_iter(); for(auto &method: methods) { diff --git a/tests/git_test.cc b/tests/git_test.cc index 258e5cc..159f027 100644 --- a/tests/git_test.cc +++ b/tests/git_test.cc @@ -11,7 +11,7 @@ int main() { auto git_path=jucipp_path/".git"; try { - auto repository=Git::get().get_repository(tests_path); + auto repository=Git::get_repository(tests_path); g_assert(repository->get_path()==git_path); g_assert(repository->get_work_path()==jucipp_path); @@ -30,7 +30,7 @@ int main() { } try { - g_assert(Git::Repository::root_path(tests_path)==git_path); + g_assert(Git::Repository::get_root_path(tests_path)==git_path); } catch(const std::exception &e) { std::cerr << e.what() << std::endl;