mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-22 07:35:08 +00:00
linux platform WIP
This commit is contained in:
parent
15b5a03a08
commit
2a08552265
@ -25,13 +25,21 @@ string(STRIP "${LIBCLANG_LIBDIR}" LIBCLANG_LIBDIR)
|
|||||||
find_library(LIBCLANG_LIBRARIES NAMES libclang clang
|
find_library(LIBCLANG_LIBRARIES NAMES libclang clang
|
||||||
PATHS ${LIBCLANG_LIBDIR})
|
PATHS ${LIBCLANG_LIBDIR})
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
set(LIBCLANG_INCLUDEDIR "/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04/include")
|
||||||
|
set(LIBCLANG_LIBDIR "/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04/lib")
|
||||||
|
set(LIBCLANG_LIBRARIES "/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.1-x86_64-linux-gnu-ubuntu-16.04/lib/libclang.so")
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Debugging
|
# Debugging
|
||||||
#
|
#
|
||||||
#message("SOURCE_FILES: " ${SOURCE_FILES} )
|
#message("SOURCE_FILES: " ${SOURCE_FILES} )
|
||||||
#message("LIBCLANG_INCLUDEDIR: " ${LIBCLANG_INCLUDEDIR})
|
message("LIBCLANG_INCLUDEDIR: " ${LIBCLANG_INCLUDEDIR})
|
||||||
#message("LIBCLANG_LIBDIR: " ${LIBCLANG_LIBDIR})
|
message("LIBCLANG_LIBDIR: " ${LIBCLANG_LIBDIR})
|
||||||
#message("LIBCLANG_LIBRARIES: " ${LIBCLANG_LIBRARIES})
|
message("LIBCLANG_LIBRARIES: " ${LIBCLANG_LIBRARIES})
|
||||||
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
|
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -Wall")
|
||||||
|
|
||||||
|
@ -164,7 +164,7 @@ namespace language_server_api {
|
|||||||
Boolean = 17,
|
Boolean = 17,
|
||||||
Array = 18
|
Array = 18
|
||||||
};
|
};
|
||||||
|
|
||||||
struct SymbolInfo {
|
struct SymbolInfo {
|
||||||
std::string name;
|
std::string name;
|
||||||
SymbolKind kind;
|
SymbolKind kind;
|
||||||
@ -187,7 +187,7 @@ IpcMessageId IpcMessage_DocumentSymbolsResponse::id = "IpcMessage_DocumentSymbol
|
|||||||
|
|
||||||
|
|
||||||
void IndexerServerMain() {
|
void IndexerServerMain() {
|
||||||
IpcServer ipc("language_server");
|
IpcServer ipc("languageserver");
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages();
|
std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages();
|
||||||
@ -206,8 +206,7 @@ void IndexerServerMain() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using namespace std::chrono_literals;
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
std::this_thread::sleep_for(20ms);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -243,7 +242,7 @@ void LanguageServerLoop(IpcClient& ipc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LanguageServerMain() {
|
void LanguageServerMain() {
|
||||||
IpcClient ipc("language_server", 0);
|
IpcClient ipc("languageserver", 0);
|
||||||
|
|
||||||
// Discard any left-over messages from previous runs.
|
// Discard any left-over messages from previous runs.
|
||||||
ipc.TakeMessages();
|
ipc.TakeMessages();
|
||||||
@ -251,8 +250,9 @@ void LanguageServerMain() {
|
|||||||
// Emit an alive check. Sleep so the server has time to respond.
|
// Emit an alive check. Sleep so the server has time to respond.
|
||||||
IpcMessage_IsAlive check_alive;
|
IpcMessage_IsAlive check_alive;
|
||||||
ipc.SendToServer(&check_alive);
|
ipc.SendToServer(&check_alive);
|
||||||
using namespace std::chrono_literals;
|
|
||||||
std::this_thread::sleep_for(50ms); // TODO: Tune this value or make it configurable.
|
// TODO: Tune this value or make it configurable.
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(20));
|
||||||
|
|
||||||
// Check if we got an IsAlive message back.
|
// Check if we got an IsAlive message back.
|
||||||
std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages();
|
std::vector<std::unique_ptr<BaseIpcMessage>> messages = ipc.TakeMessages();
|
||||||
@ -372,7 +372,7 @@ int main(int argc, char** argv) {
|
|||||||
optionally by clients if there are multiple servers running.
|
optionally by clients if there are multiple servers running.
|
||||||
--print-config
|
--print-config
|
||||||
Emit all configuration data this executable is using.
|
Emit all configuration data this executable is using.
|
||||||
|
|
||||||
|
|
||||||
Server:
|
Server:
|
||||||
--server If present, this binary will run in server mode. The binary
|
--server If present, this binary will run in server mode. The binary
|
||||||
@ -389,7 +389,7 @@ int main(int argc, char** argv) {
|
|||||||
This value is optional; a good estimate is computed by
|
This value is optional; a good estimate is computed by
|
||||||
default.
|
default.
|
||||||
|
|
||||||
|
|
||||||
Client:
|
Client:
|
||||||
--command Execute a query command against the index. See
|
--command Execute a query command against the index. See
|
||||||
--command-help for a listing of valid commands and a
|
--command-help for a listing of valid commands and a
|
||||||
|
15
ipc.cc
15
ipc.cc
@ -6,11 +6,11 @@ namespace {
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::string NameToServerName(const std::string& name) {
|
std::string NameToServerName(const std::string& name) {
|
||||||
return name + "_server";
|
return name + "server";
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string NameToClientName(const std::string& name, int client_id) {
|
std::string NameToClientName(const std::string& name, int client_id) {
|
||||||
return name + "_server_" + std::to_string(client_id);
|
return name + "client" + std::to_string(client_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +49,8 @@ std::unique_ptr<BaseIpcMessage> IpcRegistry::Allocate(int id) {
|
|||||||
|
|
||||||
IpcDirectionalChannel::IpcDirectionalChannel(const std::string& name) {
|
IpcDirectionalChannel::IpcDirectionalChannel(const std::string& name) {
|
||||||
local_block = new char[shmem_size];
|
local_block = new char[shmem_size];
|
||||||
shared = CreatePlatformSharedMemory(name + "_memory");
|
shared = CreatePlatformSharedMemory(name + "memory");
|
||||||
mutex = CreatePlatformMutex(name + "_mutex");
|
mutex = CreatePlatformMutex(name + "mutex");
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcDirectionalChannel::~IpcDirectionalChannel() {
|
IpcDirectionalChannel::~IpcDirectionalChannel() {
|
||||||
@ -71,13 +71,12 @@ void IpcDirectionalChannel::PushMessage(BaseIpcMessage* message) {
|
|||||||
bool first = true;
|
bool first = true;
|
||||||
bool did_log = false;
|
bool did_log = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
using namespace std::chrono_literals;
|
|
||||||
if (!first) {
|
if (!first) {
|
||||||
if (!did_log) {
|
if (!did_log) {
|
||||||
std::cout << "[info]: shmem full, waiting" << std::endl; // TODO: remove
|
std::cout << "[info]: shmem full, waiting" << std::endl; // TODO: remove
|
||||||
did_log = true;
|
did_log = true;
|
||||||
}
|
}
|
||||||
std::this_thread::sleep_for(16ms);
|
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
||||||
}
|
}
|
||||||
first = false;
|
first = false;
|
||||||
|
|
||||||
@ -143,7 +142,7 @@ void IpcServer::SendToClient(int client_id, BaseIpcMessage* message) {
|
|||||||
// Find or create the client.
|
// Find or create the client.
|
||||||
auto it = clients_.find(client_id);
|
auto it = clients_.find(client_id);
|
||||||
if (it == clients_.end())
|
if (it == clients_.end())
|
||||||
clients_[client_id] = std::make_unique<IpcDirectionalChannel>(NameToClientName(name_, client_id));
|
clients_[client_id] = MakeUnique<IpcDirectionalChannel>(NameToClientName(name_, client_id));
|
||||||
|
|
||||||
clients_[client_id]->PushMessage(message);
|
clients_[client_id]->PushMessage(message);
|
||||||
}
|
}
|
||||||
@ -161,4 +160,4 @@ void IpcClient::SendToServer(BaseIpcMessage* message) {
|
|||||||
|
|
||||||
std::vector<std::unique_ptr<BaseIpcMessage>> IpcClient::TakeMessages() {
|
std::vector<std::unique_ptr<BaseIpcMessage>> IpcClient::TakeMessages() {
|
||||||
return client_.TakeMessages();
|
return client_.TakeMessages();
|
||||||
}
|
}
|
||||||
|
10
ipc.h
10
ipc.h
@ -35,7 +35,7 @@ using IpcMessageId = std::string;
|
|||||||
//
|
//
|
||||||
// class IpcMessage_Foo : public BaseIpcMessage {
|
// class IpcMessage_Foo : public BaseIpcMessage {
|
||||||
// static IpcMessageId id;
|
// static IpcMessageId id;
|
||||||
//
|
//
|
||||||
// // BaseIpcMessage:
|
// // BaseIpcMessage:
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
@ -57,7 +57,7 @@ struct BaseIpcMessage {
|
|||||||
|
|
||||||
// Populated by IpcRegistry::RegisterAllocator.
|
// Populated by IpcRegistry::RegisterAllocator.
|
||||||
static IpcMessageId runtime_id_;
|
static IpcMessageId runtime_id_;
|
||||||
static int hashed_runtime_id_;
|
static int hashed_runtime_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IpcRegistry {
|
struct IpcRegistry {
|
||||||
@ -84,8 +84,8 @@ struct IpcRegistry {
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
void IpcRegistry::Register() {
|
void IpcRegistry::Register() {
|
||||||
if (!allocators) {
|
if (!allocators) {
|
||||||
allocators = std::make_unique<std::unordered_map<int, Allocator>>();
|
allocators = MakeUnique<std::unordered_map<int, Allocator>>();
|
||||||
hash_to_id = std::make_unique<std::unordered_map<int, std::string>>();
|
hash_to_id = MakeUnique<std::unordered_map<int, std::string>>();
|
||||||
}
|
}
|
||||||
|
|
||||||
IpcMessageId id = T::id;
|
IpcMessageId id = T::id;
|
||||||
@ -152,4 +152,4 @@ struct IpcClient {
|
|||||||
private:
|
private:
|
||||||
IpcDirectionalChannel server_;
|
IpcDirectionalChannel server_;
|
||||||
IpcDirectionalChannel client_;
|
IpcDirectionalChannel client_;
|
||||||
};
|
};
|
||||||
|
118
optional.h
118
optional.h
@ -101,6 +101,8 @@ namespace std{
|
|||||||
|
|
||||||
namespace experimental{
|
namespace experimental{
|
||||||
|
|
||||||
|
#define TR2_OPTIONAL_DISABLE_EMULATION_OF_TYPE_TRAITS
|
||||||
|
|
||||||
// BEGIN workaround for missing is_trivially_destructible
|
// BEGIN workaround for missing is_trivially_destructible
|
||||||
# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
|
# if defined TR2_OPTIONAL_GCC_4_8_AND_HIGHER___
|
||||||
// leave it: it is already there
|
// leave it: it is already there
|
||||||
@ -212,7 +214,7 @@ struct has_overloaded_addressof
|
|||||||
{
|
{
|
||||||
template <class X>
|
template <class X>
|
||||||
constexpr static bool has_overload(...) { return false; }
|
constexpr static bool has_overload(...) { return false; }
|
||||||
|
|
||||||
template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
|
template <class X, size_t S = sizeof(std::declval<X&>().operator&()) >
|
||||||
constexpr static bool has_overload(bool) { return true; }
|
constexpr static bool has_overload(bool) { return true; }
|
||||||
|
|
||||||
@ -232,10 +234,10 @@ T* static_addressof(T& ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// the call to convert<A>(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
|
// the call to convert<A>(b) has return type A and converts b to type A iff b decltype(b) is implicitly convertible to A
|
||||||
template <class U>
|
template <class U>
|
||||||
constexpr U convert(U v) { return v; }
|
constexpr U convert(U v) { return v; }
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
|
|
||||||
@ -352,12 +354,12 @@ class optional : private OptionalBase<T>
|
|||||||
{
|
{
|
||||||
static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
|
static_assert( !std::is_same<typename std::decay<T>::type, nullopt_t>::value, "bad T" );
|
||||||
static_assert( !std::is_same<typename std::decay<T>::type, in_place_t>::value, "bad T" );
|
static_assert( !std::is_same<typename std::decay<T>::type, in_place_t>::value, "bad T" );
|
||||||
|
|
||||||
|
|
||||||
constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
|
constexpr bool initialized() const noexcept { return OptionalBase<T>::init_; }
|
||||||
typename std::remove_const<T>::type* dataptr() { return std::addressof(OptionalBase<T>::storage_.value_); }
|
typename std::remove_const<T>::type* dataptr() { return std::addressof(OptionalBase<T>::storage_.value_); }
|
||||||
constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
|
constexpr const T* dataptr() const { return detail_::static_addressof(OptionalBase<T>::storage_.value_); }
|
||||||
|
|
||||||
# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
|
# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
|
||||||
constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
|
constexpr const T& contained_val() const& { return OptionalBase<T>::storage_.value_; }
|
||||||
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
||||||
@ -376,7 +378,7 @@ class optional : private OptionalBase<T>
|
|||||||
if (initialized()) dataptr()->T::~T();
|
if (initialized()) dataptr()->T::~T();
|
||||||
OptionalBase<T>::init_ = false;
|
OptionalBase<T>::init_ = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
void initialize(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
|
void initialize(Args&&... args) noexcept(noexcept(T(std::forward<Args>(args)...)))
|
||||||
{
|
{
|
||||||
@ -439,7 +441,7 @@ public:
|
|||||||
clear();
|
clear();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional& operator=(const optional& rhs)
|
optional& operator=(const optional& rhs)
|
||||||
{
|
{
|
||||||
if (initialized() == true && rhs.initialized() == false) clear();
|
if (initialized() == true && rhs.initialized() == false) clear();
|
||||||
@ -447,7 +449,7 @@ public:
|
|||||||
else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
|
else if (initialized() == true && rhs.initialized() == true) contained_val() = *rhs;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional& operator=(optional&& rhs)
|
optional& operator=(optional&& rhs)
|
||||||
noexcept(is_nothrow_move_assignable<T>::value && is_nothrow_move_constructible<T>::value)
|
noexcept(is_nothrow_move_assignable<T>::value && is_nothrow_move_constructible<T>::value)
|
||||||
{
|
{
|
||||||
@ -469,22 +471,22 @@ public:
|
|||||||
else { initialize(std::forward<U>(v)); }
|
else { initialize(std::forward<U>(v)); }
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class... Args>
|
template <class... Args>
|
||||||
void emplace(Args&&... args)
|
void emplace(Args&&... args)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
initialize(std::forward<Args>(args)...);
|
initialize(std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class U, class... Args>
|
template <class U, class... Args>
|
||||||
void emplace(initializer_list<U> il, Args&&... args)
|
void emplace(initializer_list<U> il, Args&&... args)
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
initialize<U, Args...>(il, std::forward<Args>(args)...);
|
initialize<U, Args...>(il, std::forward<Args>(args)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.5.4.4, Swap
|
// 20.5.4.4, Swap
|
||||||
void swap(optional<T>& rhs) noexcept(is_nothrow_move_constructible<T>::value && noexcept(swap(declval<T&>(), declval<T&>())))
|
void swap(optional<T>& rhs) noexcept(is_nothrow_move_constructible<T>::value && noexcept(swap(declval<T&>(), declval<T&>())))
|
||||||
{
|
{
|
||||||
@ -494,30 +496,30 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 20.5.4.5, Observers
|
// 20.5.4.5, Observers
|
||||||
|
|
||||||
explicit constexpr operator bool() const noexcept { return initialized(); }
|
explicit constexpr operator bool() const noexcept { return initialized(); }
|
||||||
constexpr bool has_value() const noexcept { return initialized(); }
|
constexpr bool has_value() const noexcept { return initialized(); }
|
||||||
|
|
||||||
constexpr T const* operator ->() const {
|
constexpr T const* operator ->() const {
|
||||||
return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
|
return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), dataptr());
|
||||||
}
|
}
|
||||||
|
|
||||||
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
||||||
|
|
||||||
OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
|
OPTIONAL_MUTABLE_CONSTEXPR T* operator ->() {
|
||||||
assert (initialized());
|
assert (initialized());
|
||||||
return dataptr();
|
return dataptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr T const& operator *() const& {
|
constexpr T const& operator *() const& {
|
||||||
return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
|
return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
|
OPTIONAL_MUTABLE_CONSTEXPR T& operator *() & {
|
||||||
assert (initialized());
|
assert (initialized());
|
||||||
return contained_val();
|
return contained_val();
|
||||||
}
|
}
|
||||||
|
|
||||||
OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
|
OPTIONAL_MUTABLE_CONSTEXPR T&& operator *() && {
|
||||||
assert (initialized());
|
assert (initialized());
|
||||||
return constexpr_move(contained_val());
|
return constexpr_move(contained_val());
|
||||||
@ -526,42 +528,42 @@ public:
|
|||||||
constexpr T const& value() const& {
|
constexpr T const& value() const& {
|
||||||
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
|
OPTIONAL_MUTABLE_CONSTEXPR T& value() & {
|
||||||
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
|
OPTIONAL_MUTABLE_CONSTEXPR T&& value() && {
|
||||||
if (!initialized()) throw bad_optional_access("bad optional access");
|
if (!initialized()) throw bad_optional_access("bad optional access");
|
||||||
return std::move(contained_val());
|
return std::move(contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
T* operator ->() {
|
T* operator ->() {
|
||||||
assert (initialized());
|
assert (initialized());
|
||||||
return dataptr();
|
return dataptr();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr T const& operator *() const {
|
constexpr T const& operator *() const {
|
||||||
return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
|
return TR2_OPTIONAL_ASSERTED_EXPRESSION(initialized(), contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
T& operator *() {
|
T& operator *() {
|
||||||
assert (initialized());
|
assert (initialized());
|
||||||
return contained_val();
|
return contained_val();
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr T const& value() const {
|
constexpr T const& value() const {
|
||||||
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
T& value() {
|
T& value() {
|
||||||
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
return initialized() ? contained_val() : (throw bad_optional_access("bad optional access"), contained_val());
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
|
# if OPTIONAL_HAS_THIS_RVALUE_REFS == 1
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
@ -569,7 +571,7 @@ public:
|
|||||||
{
|
{
|
||||||
return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
|
return *this ? **this : detail_::convert<T>(constexpr_forward<V>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
# if OPTIONAL_HAS_MOVE_ACCESSORS == 1
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
@ -579,17 +581,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
T value_or(V&& v) &&
|
T value_or(V&& v) &&
|
||||||
{
|
{
|
||||||
return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
|
return *this ? constexpr_move(const_cast<optional<T>&>(*this).contained_val()) : detail_::convert<T>(constexpr_forward<V>(v));
|
||||||
}
|
}
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
# else
|
# else
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
constexpr T value_or(V&& v) const
|
constexpr T value_or(V&& v) const
|
||||||
{
|
{
|
||||||
@ -609,42 +611,42 @@ class optional<T&>
|
|||||||
static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
|
static_assert( !std::is_same<T, nullopt_t>::value, "bad T" );
|
||||||
static_assert( !std::is_same<T, in_place_t>::value, "bad T" );
|
static_assert( !std::is_same<T, in_place_t>::value, "bad T" );
|
||||||
T* ref;
|
T* ref;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// 20.5.5.1, construction/destruction
|
// 20.5.5.1, construction/destruction
|
||||||
constexpr optional() noexcept : ref(nullptr) {}
|
constexpr optional() noexcept : ref(nullptr) {}
|
||||||
|
|
||||||
constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
|
constexpr optional(nullopt_t) noexcept : ref(nullptr) {}
|
||||||
|
|
||||||
constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
|
constexpr optional(T& v) noexcept : ref(detail_::static_addressof(v)) {}
|
||||||
|
|
||||||
optional(T&&) = delete;
|
optional(T&&) = delete;
|
||||||
|
|
||||||
constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
|
constexpr optional(const optional& rhs) noexcept : ref(rhs.ref) {}
|
||||||
|
|
||||||
explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
|
explicit constexpr optional(in_place_t, T& v) noexcept : ref(detail_::static_addressof(v)) {}
|
||||||
|
|
||||||
explicit optional(in_place_t, T&&) = delete;
|
explicit optional(in_place_t, T&&) = delete;
|
||||||
|
|
||||||
~optional() = default;
|
~optional() = default;
|
||||||
|
|
||||||
// 20.5.5.2, mutation
|
// 20.5.5.2, mutation
|
||||||
optional& operator=(nullopt_t) noexcept {
|
optional& operator=(nullopt_t) noexcept {
|
||||||
ref = nullptr;
|
ref = nullptr;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
// optional& operator=(const optional& rhs) noexcept {
|
// optional& operator=(const optional& rhs) noexcept {
|
||||||
// ref = rhs.ref;
|
// ref = rhs.ref;
|
||||||
// return *this;
|
// return *this;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
// optional& operator=(optional&& rhs) noexcept {
|
// optional& operator=(optional&& rhs) noexcept {
|
||||||
// ref = rhs.ref;
|
// ref = rhs.ref;
|
||||||
// return *this;
|
// return *this;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
auto operator=(U&& rhs) noexcept
|
auto operator=(U&& rhs) noexcept
|
||||||
-> typename enable_if
|
-> typename enable_if
|
||||||
@ -656,7 +658,7 @@ public:
|
|||||||
ref = rhs.ref;
|
ref = rhs.ref;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename U>
|
template <typename U>
|
||||||
auto operator=(U&& rhs) noexcept
|
auto operator=(U&& rhs) noexcept
|
||||||
-> typename enable_if
|
-> typename enable_if
|
||||||
@ -665,40 +667,40 @@ public:
|
|||||||
optional&
|
optional&
|
||||||
>::type
|
>::type
|
||||||
= delete;
|
= delete;
|
||||||
|
|
||||||
void emplace(T& v) noexcept {
|
void emplace(T& v) noexcept {
|
||||||
ref = detail_::static_addressof(v);
|
ref = detail_::static_addressof(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void emplace(T&&) = delete;
|
void emplace(T&&) = delete;
|
||||||
|
|
||||||
|
|
||||||
void swap(optional<T&>& rhs) noexcept
|
void swap(optional<T&>& rhs) noexcept
|
||||||
{
|
{
|
||||||
std::swap(ref, rhs.ref);
|
std::swap(ref, rhs.ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 20.5.5.3, observers
|
// 20.5.5.3, observers
|
||||||
constexpr T* operator->() const {
|
constexpr T* operator->() const {
|
||||||
return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
|
return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr T& operator*() const {
|
constexpr T& operator*() const {
|
||||||
return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
|
return TR2_OPTIONAL_ASSERTED_EXPRESSION(ref, *ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr T& value() const {
|
constexpr T& value() const {
|
||||||
return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
|
return ref ? *ref : (throw bad_optional_access("bad optional access"), *ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit constexpr operator bool() const noexcept {
|
explicit constexpr operator bool() const noexcept {
|
||||||
return ref != nullptr;
|
return ref != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool has_value() const noexcept {
|
constexpr bool has_value() const noexcept {
|
||||||
return ref != nullptr;
|
return ref != nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class V>
|
template <class V>
|
||||||
constexpr typename decay<T>::type value_or(V&& v) const
|
constexpr typename decay<T>::type value_or(V&& v) const
|
||||||
{
|
{
|
||||||
@ -1028,18 +1030,18 @@ namespace std
|
|||||||
{
|
{
|
||||||
typedef typename hash<T>::result_type result_type;
|
typedef typename hash<T>::result_type result_type;
|
||||||
typedef std::experimental::optional<T> argument_type;
|
typedef std::experimental::optional<T> argument_type;
|
||||||
|
|
||||||
constexpr result_type operator()(argument_type const& arg) const {
|
constexpr result_type operator()(argument_type const& arg) const {
|
||||||
return arg ? std::hash<T>{}(*arg) : result_type{};
|
return arg ? std::hash<T>{}(*arg) : result_type{};
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct hash<std::experimental::optional<T&>>
|
struct hash<std::experimental::optional<T&>>
|
||||||
{
|
{
|
||||||
typedef typename hash<T>::result_type result_type;
|
typedef typename hash<T>::result_type result_type;
|
||||||
typedef std::experimental::optional<T&> argument_type;
|
typedef std::experimental::optional<T&> argument_type;
|
||||||
|
|
||||||
constexpr result_type operator()(argument_type const& arg) const {
|
constexpr result_type operator()(argument_type const& arg) const {
|
||||||
return arg ? std::hash<T>{}(*arg) : result_type{};
|
return arg ? std::hash<T>{}(*arg) : result_type{};
|
||||||
}
|
}
|
||||||
|
118
platform_linux.cc
Normal file
118
platform_linux.cc
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
#include "platform.h"
|
||||||
|
|
||||||
|
#include "utils.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <string>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include <fcntl.h> /* For O_* constants */
|
||||||
|
#include <sys/stat.h> /* For mode constants */
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
#include <sys/stat.h> /* For mode constants */
|
||||||
|
#include <fcntl.h> /* For O_* constants */
|
||||||
|
|
||||||
|
struct PlatformMutexLinux : public PlatformMutex {
|
||||||
|
sem_t* sem_ = nullptr;
|
||||||
|
|
||||||
|
PlatformMutexLinux(const std::string& name) {
|
||||||
|
std::cout << "PlatformMutexLinux name=" << name << std::endl;
|
||||||
|
sem_ = sem_open(name.c_str(), O_CREAT, 0666 /*permission*/, 1 /*initial_value*/);
|
||||||
|
}
|
||||||
|
|
||||||
|
~PlatformMutexLinux() override {
|
||||||
|
sem_close(sem_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlatformScopedMutexLockLinux : public PlatformScopedMutexLock {
|
||||||
|
sem_t* sem_ = nullptr;
|
||||||
|
|
||||||
|
PlatformScopedMutexLockLinux(sem_t* sem) : sem_(sem) {
|
||||||
|
std::cout << "PlatformScopedMutexLockLinux" << std::endl;
|
||||||
|
sem_wait(sem_);
|
||||||
|
}
|
||||||
|
|
||||||
|
~PlatformScopedMutexLockLinux() override {
|
||||||
|
sem_post(sem_);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PlatformSharedMemoryLinux : public PlatformSharedMemory {
|
||||||
|
std::string name_;
|
||||||
|
int fd_;
|
||||||
|
void* shared_start_real_;
|
||||||
|
|
||||||
|
PlatformSharedMemoryLinux(const std::string& name) : name_(name) {
|
||||||
|
std::cout << "PlatformSharedMemoryLinux name=" << name << std::endl;
|
||||||
|
fd_ = shm_open(name_.c_str(), O_CREAT, O_RDWR);
|
||||||
|
std::cout << "shm_open errno=" << errno << std::endl;
|
||||||
|
std::cout << "1" << std::endl;
|
||||||
|
ftruncate(fd_, shmem_size);
|
||||||
|
std::cout << "ftruncate errno=" << errno << std::endl;
|
||||||
|
std::cout << "2" << std::endl;
|
||||||
|
|
||||||
|
//void *mmap(void *addr, size_t length, int prot, int flags,
|
||||||
|
// int fd, off_t offset);
|
||||||
|
//int munmap(void *addr, size_t length);
|
||||||
|
//
|
||||||
|
//shmem_size
|
||||||
|
std::cout << "3" << std::endl;
|
||||||
|
shared_start_real_ = mmap(nullptr /*kernel assigned starting address*/,
|
||||||
|
shmem_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd_, 0 /*offset*/);
|
||||||
|
std::cout << "mmap errno=" << errno << std::endl;
|
||||||
|
std::cout << "fd_ = " << fd_ << std::endl;
|
||||||
|
std::cout << "shared_start_real_ = " << shared_start_real_ << std::endl;
|
||||||
|
std::cout << "4" << std::endl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
int fd = shm_open("shmname", O_CREAT, O_RDWR);
|
||||||
|
sem_t *sem = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
|
||||||
|
ftruncate(fd_, shmem_size);
|
||||||
|
|
||||||
|
sem_init(sem, 1, 1);
|
||||||
|
*/
|
||||||
|
|
||||||
|
std::cout << "4a" << std::endl;
|
||||||
|
shared_bytes_used = reinterpret_cast<size_t*>(shared_start_real_);
|
||||||
|
std::cout << "4b" << std::endl;
|
||||||
|
*shared_bytes_used = 0;
|
||||||
|
std::cout << "4c" << std::endl;
|
||||||
|
shared_start = reinterpret_cast<char*>(shared_bytes_used + 1);
|
||||||
|
std::cout << "5" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
~PlatformSharedMemoryLinux() override {
|
||||||
|
munmap(shared_start_real_, shmem_size);
|
||||||
|
shm_unlink(name_.c_str());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) {
|
||||||
|
std::string name2 = "/" + name;
|
||||||
|
return MakeUnique<PlatformMutexLinux>(name2);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(PlatformMutex* mutex) {
|
||||||
|
return MakeUnique<PlatformScopedMutexLockLinux>(static_cast<PlatformMutexLinux*>(mutex)->sem_);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(const std::string& name) {
|
||||||
|
std::string name2 = "/" + name;
|
||||||
|
return MakeUnique<PlatformSharedMemoryLinux>(name2);
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
|
#if false
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@ -59,13 +60,14 @@ struct PlatformSharedMemoryWin : public PlatformSharedMemory {
|
|||||||
|
|
||||||
|
|
||||||
std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) {
|
std::unique_ptr<PlatformMutex> CreatePlatformMutex(const std::string& name) {
|
||||||
return std::make_unique<PlatformMutexWin>(name);
|
return MakeUnique<PlatformMutexWin>(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(PlatformMutex* mutex) {
|
std::unique_ptr<PlatformScopedMutexLock> CreatePlatformScopedMutexLock(PlatformMutex* mutex) {
|
||||||
return std::make_unique<PlatformScopedMutexLockWin>(static_cast<PlatformMutexWin*>(mutex)->raw_mutex);
|
return MakeUnique<PlatformScopedMutexLockWin>(static_cast<PlatformMutexWin*>(mutex)->raw_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(const std::string& name) {
|
std::unique_ptr<PlatformSharedMemory> CreatePlatformSharedMemory(const std::string& name) {
|
||||||
return std::make_unique<PlatformSharedMemoryWin>(name);
|
return MakeUnique<PlatformSharedMemoryWin>(name);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
10
utils.h
10
utils.h
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
std::vector<std::string> GetFilesInFolder(std::string folder);
|
std::vector<std::string> GetFilesInFolder(std::string folder);
|
||||||
std::vector<std::string> ReadLines(std::string filename);
|
std::vector<std::string> ReadLines(std::string filename);
|
||||||
@ -10,4 +11,11 @@ void ParseTestExpectation(std::string filename, std::string* expected_output);
|
|||||||
void Fail(const std::string& message);
|
void Fail(const std::string& message);
|
||||||
|
|
||||||
|
|
||||||
void WriteToFile(const std::string& filename, const std::string& content);
|
void WriteToFile(const std::string& filename, const std::string& content);
|
||||||
|
|
||||||
|
// note: this implementation does not disable this overload for array types
|
||||||
|
// See http://en.cppreference.com/w/cpp/memory/unique_ptr/make_unique#Possible_Implementatiog
|
||||||
|
template<typename T, typename... Args>
|
||||||
|
std::unique_ptr<T> MakeUnique(Args&&... args) {
|
||||||
|
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||||
|
}
|
||||||
|
18
wscript
18
wscript
@ -1,12 +1,17 @@
|
|||||||
#! /usr/bin/env python
|
#! /usr/bin/env python
|
||||||
# encoding: utf-8
|
# encoding: utf-8
|
||||||
|
|
||||||
|
import urllib2
|
||||||
|
|
||||||
VERSION='0.0.1'
|
VERSION='0.0.1'
|
||||||
APPNAME='indexer'
|
APPNAME='indexer'
|
||||||
|
|
||||||
top = '.'
|
top = '.'
|
||||||
out = 'build'
|
out = 'build'
|
||||||
|
|
||||||
|
from waflib.Tools.compiler_cxx import cxx_compiler
|
||||||
|
cxx_compiler['linux'] = ['clang++', 'g++']
|
||||||
|
|
||||||
def options(opt):
|
def options(opt):
|
||||||
opt.load('compiler_cxx')
|
opt.load('compiler_cxx')
|
||||||
|
|
||||||
@ -15,8 +20,10 @@ def configure(conf):
|
|||||||
conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=True)
|
conf.check(header_name='stdio.h', features='cxx cxxprogram', mandatory=True)
|
||||||
|
|
||||||
# https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh
|
# https://github.com/Andersbakken/rtags/blob/master/scripts/getclang.sh
|
||||||
def download_clang():
|
def download_clang(conf):
|
||||||
#'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz'
|
url = 'http://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-apple-darwin.tar.xz'
|
||||||
|
response = urllib2.urlopen(url)
|
||||||
|
html = response.read()
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def build(bld):
|
def build(bld):
|
||||||
@ -24,8 +31,11 @@ def build(bld):
|
|||||||
excl=['*tests/*', 'third_party/*'])
|
excl=['*tests/*', 'third_party/*'])
|
||||||
bld.program(
|
bld.program(
|
||||||
source=cc_files,
|
source=cc_files,
|
||||||
cxxflags=['-std=c++14'],
|
cxxflags=['-std=c++11'],
|
||||||
includes=['third_party/rapidjson/include'],
|
includes=['third_party/rapidjson/include',
|
||||||
|
'/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04/include'],
|
||||||
|
lib=['clang', 'rt', 'pthread'],
|
||||||
|
libpath=['/usr/local/google/home/jdufault/super-clang-index/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-14.04/lib'],
|
||||||
target='app')
|
target='app')
|
||||||
|
|
||||||
#bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7')
|
#bld.shlib(source='a.cpp', target='mylib', vnum='9.8.7')
|
||||||
|
Loading…
Reference in New Issue
Block a user