Formatting more code with astyle
This commit is contained in:
parent
013a56c25c
commit
4308130ab3
@ -24,23 +24,18 @@
|
|||||||
using boost::algorithm::all;
|
using boost::algorithm::all;
|
||||||
using boost::algorithm::is_lower;
|
using boost::algorithm::is_lower;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
std::string GetWordBoundaryChars( const std::string &text )
|
std::string GetWordBoundaryChars( const std::string &text ) {
|
||||||
{
|
|
||||||
std::string result;
|
std::string result;
|
||||||
|
|
||||||
for ( uint i = 0; i < text.size(); ++i )
|
for ( uint i = 0; i < text.size(); ++i ) {
|
||||||
{
|
|
||||||
if ( i == 0 ||
|
if ( i == 0 ||
|
||||||
IsUppercase( text[ i ] ) ||
|
IsUppercase( text[ i ] ) ||
|
||||||
( i > 0 && text[ i - 1 ] == '_' && isalpha( text[ i ] ) )
|
( i > 0 && text[ i - 1 ] == '_' && isalpha( text[ i ] ) )
|
||||||
)
|
) {
|
||||||
{
|
|
||||||
result.push_back( tolower( text[ i ] ) );
|
result.push_back( tolower( text[ i ] ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,11 +46,9 @@ std::string GetWordBoundaryChars( const std::string &text )
|
|||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
Bitset LetterBitsetFromString( const std::string &text )
|
Bitset LetterBitsetFromString( const std::string &text ) {
|
||||||
{
|
|
||||||
Bitset letter_bitset;
|
Bitset letter_bitset;
|
||||||
foreach ( char letter, text )
|
foreach ( char letter, text ) {
|
||||||
{
|
|
||||||
letter_bitset.set( IndexForChar( letter ) );
|
letter_bitset.set( IndexForChar( letter ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,19 +62,17 @@ Candidate::Candidate( const std::string &text )
|
|||||||
word_boundary_chars_( GetWordBoundaryChars( text ) ),
|
word_boundary_chars_( GetWordBoundaryChars( text ) ),
|
||||||
text_is_lowercase_( all( text, is_lower() ) ),
|
text_is_lowercase_( all( text, is_lower() ) ),
|
||||||
letters_present_( LetterBitsetFromString( text ) ),
|
letters_present_( LetterBitsetFromString( text ) ),
|
||||||
root_node_( new LetterNode( text ) )
|
root_node_( new LetterNode( text ) ) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Result Candidate::QueryMatchResult( const std::string &query ) const
|
Result Candidate::QueryMatchResult( const std::string &query ) const {
|
||||||
{
|
|
||||||
LetterNode *node = root_node_.get();
|
LetterNode *node = root_node_.get();
|
||||||
int index_sum = 0;
|
int index_sum = 0;
|
||||||
|
|
||||||
foreach ( char letter, query )
|
foreach ( char letter, query ) {
|
||||||
{
|
|
||||||
const std::list< LetterNode *> *list = node->NodeListForLetter( letter );
|
const std::list< LetterNode *> *list = node->NodeListForLetter( letter );
|
||||||
|
|
||||||
if ( !list )
|
if ( !list )
|
||||||
|
|
||||||
return Result( false );
|
return Result( false );
|
||||||
|
@ -26,8 +26,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <bitset>
|
#include <bitset>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class Result;
|
class Result;
|
||||||
|
|
||||||
@ -35,21 +34,18 @@ typedef std::bitset< NUM_LETTERS > Bitset;
|
|||||||
|
|
||||||
Bitset LetterBitsetFromString( const std::string &text );
|
Bitset LetterBitsetFromString( const std::string &text );
|
||||||
|
|
||||||
class Candidate : boost::noncopyable
|
class Candidate : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
explicit Candidate( const std::string &text );
|
explicit Candidate( const std::string &text );
|
||||||
|
|
||||||
inline const std::string& Text() const
|
inline const std::string &Text() const {
|
||||||
{
|
|
||||||
return text_;
|
return text_;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the candidate contains the bits from the query (it may also
|
// Returns true if the candidate contains the bits from the query (it may also
|
||||||
// contain other bits)
|
// contain other bits)
|
||||||
inline bool MatchesQueryBitset( const Bitset &query_bitset ) const
|
inline bool MatchesQueryBitset( const Bitset &query_bitset ) const {
|
||||||
{
|
|
||||||
return ( letters_present_ & query_bitset ) == query_bitset;
|
return ( letters_present_ & query_bitset ) == query_bitset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,18 +26,15 @@
|
|||||||
# include "CompletionData.h"
|
# include "CompletionData.h"
|
||||||
#endif // USE_CLANG_COMPLETER
|
#endif // USE_CLANG_COMPLETER
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
boost::mutex CandidateRepository::singleton_mutex_;
|
boost::mutex CandidateRepository::singleton_mutex_;
|
||||||
CandidateRepository *CandidateRepository::instance_ = NULL;
|
CandidateRepository *CandidateRepository::instance_ = NULL;
|
||||||
|
|
||||||
CandidateRepository& CandidateRepository::Instance()
|
CandidateRepository &CandidateRepository::Instance() {
|
||||||
{
|
|
||||||
boost::lock_guard< boost::mutex > locker( singleton_mutex_ );
|
boost::lock_guard< boost::mutex > locker( singleton_mutex_ );
|
||||||
|
|
||||||
if ( !instance_ )
|
if ( !instance_ ) {
|
||||||
{
|
|
||||||
static CandidateRepository repo;
|
static CandidateRepository repo;
|
||||||
instance_ = &repo;
|
instance_ = &repo;
|
||||||
}
|
}
|
||||||
@ -46,27 +43,25 @@ CandidateRepository& CandidateRepository::Instance()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int CandidateRepository::NumStoredCandidates()
|
int CandidateRepository::NumStoredCandidates() {
|
||||||
{
|
|
||||||
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
||||||
return candidate_holder_.size();
|
return candidate_holder_.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
std::vector< const Candidate * > CandidateRepository::GetCandidatesForStrings(
|
||||||
const std::vector< std::string > &strings )
|
const std::vector< std::string > &strings ) {
|
||||||
{
|
std::vector< const Candidate * > candidates;
|
||||||
std::vector< const Candidate* > candidates;
|
|
||||||
candidates.reserve( strings.size() );
|
candidates.reserve( strings.size() );
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
||||||
|
|
||||||
foreach ( const std::string &candidate_text, strings )
|
foreach ( const std::string & candidate_text, strings ) {
|
||||||
{
|
|
||||||
const Candidate *&candidate = GetValueElseInsert( candidate_holder_,
|
const Candidate *&candidate = GetValueElseInsert( candidate_holder_,
|
||||||
candidate_text,
|
candidate_text,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( !candidate )
|
if ( !candidate )
|
||||||
candidate = new Candidate( candidate_text );
|
candidate = new Candidate( candidate_text );
|
||||||
|
|
||||||
@ -79,20 +74,19 @@ std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
|||||||
|
|
||||||
#ifdef USE_CLANG_COMPLETER
|
#ifdef USE_CLANG_COMPLETER
|
||||||
|
|
||||||
std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
std::vector< const Candidate * > CandidateRepository::GetCandidatesForStrings(
|
||||||
const std::vector< CompletionData > &datas )
|
const std::vector< CompletionData > &datas ) {
|
||||||
{
|
std::vector< const Candidate * > candidates;
|
||||||
std::vector< const Candidate* > candidates;
|
|
||||||
candidates.reserve( datas.size() );
|
candidates.reserve( datas.size() );
|
||||||
|
|
||||||
{
|
{
|
||||||
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
boost::lock_guard< boost::mutex > locker( holder_mutex_ );
|
||||||
|
|
||||||
foreach ( const CompletionData &data, datas )
|
foreach ( const CompletionData & data, datas ) {
|
||||||
{
|
|
||||||
const Candidate *&candidate = GetValueElseInsert( candidate_holder_,
|
const Candidate *&candidate = GetValueElseInsert( candidate_holder_,
|
||||||
data.original_string_,
|
data.original_string_,
|
||||||
NULL );
|
NULL );
|
||||||
|
|
||||||
if ( !candidate )
|
if ( !candidate )
|
||||||
candidate = new Candidate( data.original_string_ );
|
candidate = new Candidate( data.original_string_ );
|
||||||
|
|
||||||
@ -105,11 +99,9 @@ std::vector< const Candidate* > CandidateRepository::GetCandidatesForStrings(
|
|||||||
|
|
||||||
#endif // USE_CLANG_COMPLETER
|
#endif // USE_CLANG_COMPLETER
|
||||||
|
|
||||||
CandidateRepository::~CandidateRepository()
|
CandidateRepository::~CandidateRepository() {
|
||||||
{
|
foreach ( const CandidateHolder::value_type & pair,
|
||||||
foreach ( const CandidateHolder::value_type &pair,
|
candidate_holder_ ) {
|
||||||
candidate_holder_ )
|
|
||||||
{
|
|
||||||
delete pair.second;
|
delete pair.second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,28 +25,26 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class Candidate;
|
class Candidate;
|
||||||
struct CompletionData;
|
struct CompletionData;
|
||||||
|
|
||||||
typedef boost::unordered_map< std::string, const Candidate* >
|
typedef boost::unordered_map< std::string, const Candidate * >
|
||||||
CandidateHolder;
|
CandidateHolder;
|
||||||
|
|
||||||
class CandidateRepository : boost::noncopyable
|
class CandidateRepository : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
static CandidateRepository& Instance();
|
static CandidateRepository &Instance();
|
||||||
|
|
||||||
int NumStoredCandidates();
|
int NumStoredCandidates();
|
||||||
|
|
||||||
std::vector< const Candidate* > GetCandidatesForStrings(
|
std::vector< const Candidate * > GetCandidatesForStrings(
|
||||||
const std::vector< std::string > &strings );
|
const std::vector< std::string > &strings );
|
||||||
|
|
||||||
#ifdef USE_CLANG_COMPLETER
|
#ifdef USE_CLANG_COMPLETER
|
||||||
std::vector< const Candidate* > GetCandidatesForStrings(
|
std::vector< const Candidate * > GetCandidatesForStrings(
|
||||||
const std::vector< CompletionData > &datas );
|
const std::vector< CompletionData > &datas );
|
||||||
#endif // USE_CLANG_COMPLETER
|
#endif // USE_CLANG_COMPLETER
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
#include <boost/thread.hpp>
|
#include <boost/thread.hpp>
|
||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
// This is is basically a multi-consumer single-producer queue, only with the
|
// This is is basically a multi-consumer single-producer queue, only with the
|
||||||
// twist that we only care about the latest value set. So the GUI thread is the
|
// twist that we only care about the latest value set. So the GUI thread is the
|
||||||
@ -40,14 +39,12 @@ namespace YouCompleteMe
|
|||||||
// nanoseconds it takes to lock a mutex are laughably negligible compared to the
|
// nanoseconds it takes to lock a mutex are laughably negligible compared to the
|
||||||
// VimL/Python overhead.
|
// VimL/Python overhead.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ConcurrentLatestValue : boost::noncopyable
|
class ConcurrentLatestValue : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ConcurrentLatestValue() : empty_( true ) {}
|
ConcurrentLatestValue() : empty_( true ) {}
|
||||||
|
|
||||||
void Set( const T& data )
|
void Set( const T &data ) {
|
||||||
{
|
|
||||||
{
|
{
|
||||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
latest_ = data;
|
latest_ = data;
|
||||||
@ -57,12 +54,10 @@ public:
|
|||||||
condition_variable_.notify_one();
|
condition_variable_.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
T Get()
|
T Get() {
|
||||||
{
|
|
||||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
|
|
||||||
while ( empty_ )
|
while ( empty_ ) {
|
||||||
{
|
|
||||||
condition_variable_.wait( lock );
|
condition_variable_.wait( lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,16 +22,13 @@
|
|||||||
#include <boost/utility.hpp>
|
#include <boost/utility.hpp>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
class ConcurrentStack : boost::noncopyable
|
class ConcurrentStack : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void Push( const T& data )
|
void Push( const T &data ) {
|
||||||
{
|
|
||||||
{
|
{
|
||||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
stack_.push( data );
|
stack_.push( data );
|
||||||
@ -40,12 +37,10 @@ public:
|
|||||||
condition_variable_.notify_one();
|
condition_variable_.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
T Pop()
|
T Pop() {
|
||||||
{
|
|
||||||
boost::unique_lock< boost::mutex > lock( mutex_ );
|
boost::unique_lock< boost::mutex > lock( mutex_ );
|
||||||
|
|
||||||
while ( stack_.empty() )
|
while ( stack_.empty() ) {
|
||||||
{
|
|
||||||
condition_variable_.wait( lock );
|
condition_variable_.wait( lock );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -23,30 +23,26 @@
|
|||||||
#include <boost/shared_ptr.hpp>
|
#include <boost/shared_ptr.hpp>
|
||||||
#include <boost/function.hpp>
|
#include <boost/function.hpp>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class Result;
|
class Result;
|
||||||
typedef boost::shared_ptr< boost::packaged_task< void > > VoidTask;
|
typedef boost::shared_ptr< boost::packaged_task< void > > VoidTask;
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
boost::shared_ptr< T > ReturnValueAsShared(
|
boost::shared_ptr< T > ReturnValueAsShared(
|
||||||
boost::function< T() > func )
|
boost::function< T() > func ) {
|
||||||
{
|
|
||||||
return boost::make_shared< T >( func() );
|
return boost::make_shared< T >( func() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template< typename T >
|
template< typename T >
|
||||||
class Future
|
class Future {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Future() {};
|
Future() {};
|
||||||
Future( boost::shared_future< T > future )
|
Future( boost::shared_future< T > future )
|
||||||
: future_( boost::move( future ) ) {}
|
: future_( boost::move( future ) ) {}
|
||||||
|
|
||||||
bool ResultsReady()
|
bool ResultsReady() {
|
||||||
{
|
|
||||||
// It's OK to return true since GetResults will just return a
|
// It's OK to return true since GetResults will just return a
|
||||||
// default-constructed value if the future_ is uninitialized. If we don't
|
// default-constructed value if the future_ is uninitialized. If we don't
|
||||||
// return true for this case, any loop waiting on ResultsReady will wait
|
// return true for this case, any loop waiting on ResultsReady will wait
|
||||||
@ -58,21 +54,17 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Wait()
|
void Wait() {
|
||||||
{
|
|
||||||
future_.wait();
|
future_.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
T GetResults()
|
T GetResults() {
|
||||||
{
|
try {
|
||||||
try
|
|
||||||
{
|
|
||||||
return future_.get();
|
return future_.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
catch ( boost::future_uninitialized & )
|
catch ( boost::future_uninitialized & ) {
|
||||||
{
|
|
||||||
// Do nothing and return a T()
|
// Do nothing and return a T()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,29 +36,22 @@ using boost::shared_ptr;
|
|||||||
using boost::bind;
|
using boost::bind;
|
||||||
using boost::thread;
|
using boost::thread;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
typedef boost::function< std::vector< std::string >() >
|
typedef boost::function< std::vector< std::string >() >
|
||||||
FunctionReturnsStringVector;
|
FunctionReturnsStringVector;
|
||||||
|
|
||||||
|
|
||||||
extern const unsigned int MAX_ASYNC_THREADS = 4;
|
extern const unsigned int MAX_ASYNC_THREADS = 4;
|
||||||
extern const unsigned int MIN_ASYNC_THREADS = 2;
|
extern const unsigned int MIN_ASYNC_THREADS = 2;
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
void QueryThreadMain( IdentifierCompleter::LatestQueryTask &latest_query_task )
|
void QueryThreadMain( IdentifierCompleter::LatestQueryTask &latest_query_task ) {
|
||||||
{
|
while ( true ) {
|
||||||
while ( true )
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
( *latest_query_task.Get() )();
|
( *latest_query_task.Get() )();
|
||||||
}
|
} catch ( boost::thread_interrupted & ) {
|
||||||
catch ( boost::thread_interrupted& )
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,16 +60,11 @@ void QueryThreadMain( IdentifierCompleter::LatestQueryTask &latest_query_task )
|
|||||||
|
|
||||||
void BufferIdentifiersThreadMain(
|
void BufferIdentifiersThreadMain(
|
||||||
IdentifierCompleter::BufferIdentifiersTaskStack
|
IdentifierCompleter::BufferIdentifiersTaskStack
|
||||||
&buffer_identifiers_task_stack )
|
&buffer_identifiers_task_stack ) {
|
||||||
{
|
while ( true ) {
|
||||||
while ( true )
|
try {
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
( *buffer_identifiers_task_stack.Pop() )();
|
( *buffer_identifiers_task_stack.Pop() )();
|
||||||
}
|
} catch ( boost::thread_interrupted & ) {
|
||||||
catch ( boost::thread_interrupted& )
|
|
||||||
{
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,33 +76,29 @@ void BufferIdentifiersThreadMain(
|
|||||||
|
|
||||||
IdentifierCompleter::IdentifierCompleter()
|
IdentifierCompleter::IdentifierCompleter()
|
||||||
: candidate_repository_( CandidateRepository::Instance() ),
|
: candidate_repository_( CandidateRepository::Instance() ),
|
||||||
threading_enabled_( false )
|
threading_enabled_( false ) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IdentifierCompleter::IdentifierCompleter(
|
IdentifierCompleter::IdentifierCompleter(
|
||||||
const std::vector< std::string > &candidates )
|
const std::vector< std::string > &candidates )
|
||||||
: candidate_repository_( CandidateRepository::Instance() ),
|
: candidate_repository_( CandidateRepository::Instance() ),
|
||||||
threading_enabled_( false )
|
threading_enabled_( false ) {
|
||||||
{
|
|
||||||
AddCandidatesToDatabase( candidates, "", "" );
|
AddCandidatesToDatabase( candidates, "", "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IdentifierCompleter::IdentifierCompleter(
|
IdentifierCompleter::IdentifierCompleter(
|
||||||
const std::vector< std::string > &candidates,
|
const std::vector< std::string > &candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath )
|
const std::string &filepath )
|
||||||
: candidate_repository_( CandidateRepository::Instance() ),
|
: candidate_repository_( CandidateRepository::Instance() ),
|
||||||
threading_enabled_( false )
|
threading_enabled_( false ) {
|
||||||
{
|
|
||||||
AddCandidatesToDatabase( candidates, filetype, filepath );
|
AddCandidatesToDatabase( candidates, filetype, filepath );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
IdentifierCompleter::~IdentifierCompleter()
|
IdentifierCompleter::~IdentifierCompleter() {
|
||||||
{
|
|
||||||
query_threads_.interrupt_all();
|
query_threads_.interrupt_all();
|
||||||
query_threads_.join_all();
|
query_threads_.join_all();
|
||||||
|
|
||||||
@ -125,22 +109,20 @@ IdentifierCompleter::~IdentifierCompleter()
|
|||||||
|
|
||||||
// We need this mostly so that we can not use it in tests. Apparently the
|
// We need this mostly so that we can not use it in tests. Apparently the
|
||||||
// GoogleTest framework goes apeshit on us if we enable threads by default.
|
// GoogleTest framework goes apeshit on us if we enable threads by default.
|
||||||
void IdentifierCompleter::EnableThreading()
|
void IdentifierCompleter::EnableThreading() {
|
||||||
{
|
|
||||||
threading_enabled_ = true;
|
threading_enabled_ = true;
|
||||||
InitThreads();
|
InitThreads();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IdentifierCompleter::AddCandidatesToDatabase(
|
void IdentifierCompleter::AddCandidatesToDatabase(
|
||||||
const std::vector< std::string > &new_candidates,
|
const std::vector< std::string > &new_candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath )
|
const std::string &filepath ) {
|
||||||
{
|
|
||||||
std::list< const Candidate *> &candidates =
|
std::list< const Candidate *> &candidates =
|
||||||
GetCandidateList( filetype, filepath );
|
GetCandidateList( filetype, filepath );
|
||||||
|
|
||||||
std::vector< const Candidate* > repository_candidates =
|
std::vector< const Candidate * > repository_candidates =
|
||||||
candidate_repository_.GetCandidatesForStrings( new_candidates );
|
candidate_repository_.GetCandidatesForStrings( new_candidates );
|
||||||
|
|
||||||
candidates.insert( candidates.end(),
|
candidates.insert( candidates.end(),
|
||||||
@ -150,24 +132,22 @@ void IdentifierCompleter::AddCandidatesToDatabase(
|
|||||||
|
|
||||||
|
|
||||||
void IdentifierCompleter::AddCandidatesToDatabaseFromBuffer(
|
void IdentifierCompleter::AddCandidatesToDatabaseFromBuffer(
|
||||||
const std::string &buffer_contents,
|
const std::string &buffer_contents,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath )
|
const std::string &filepath ) {
|
||||||
{
|
|
||||||
ClearCandidatesStoredForFile( filetype, filepath );
|
ClearCandidatesStoredForFile( filetype, filepath );
|
||||||
|
|
||||||
AddCandidatesToDatabase(
|
AddCandidatesToDatabase(
|
||||||
ExtractIdentifiersFromText( RemoveIdentifierFreeText( buffer_contents ) ),
|
ExtractIdentifiersFromText( RemoveIdentifierFreeText( buffer_contents ) ),
|
||||||
filetype,
|
filetype,
|
||||||
filepath );
|
filepath );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IdentifierCompleter::AddCandidatesToDatabaseFromBufferAsync(
|
void IdentifierCompleter::AddCandidatesToDatabaseFromBufferAsync(
|
||||||
std::string buffer_contents,
|
std::string buffer_contents,
|
||||||
std::string filetype,
|
std::string filetype,
|
||||||
std::string filepath )
|
std::string filepath ) {
|
||||||
{
|
|
||||||
// TODO: throw exception when threading is not enabled and this is called
|
// TODO: throw exception when threading is not enabled and this is called
|
||||||
if ( !threading_enabled_ )
|
if ( !threading_enabled_ )
|
||||||
return;
|
return;
|
||||||
@ -180,29 +160,26 @@ void IdentifierCompleter::AddCandidatesToDatabaseFromBufferAsync(
|
|||||||
boost::move( filepath ) );
|
boost::move( filepath ) );
|
||||||
|
|
||||||
buffer_identifiers_task_stack_.Push(
|
buffer_identifiers_task_stack_.Push(
|
||||||
make_shared< packaged_task< void > >( functor ) );
|
make_shared< packaged_task< void > >( functor ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > IdentifierCompleter::CandidatesForQuery(
|
std::vector< std::string > IdentifierCompleter::CandidatesForQuery(
|
||||||
const std::string &query ) const
|
const std::string &query ) const {
|
||||||
{
|
|
||||||
return CandidatesForQueryAndType( query, "" );
|
return CandidatesForQueryAndType( query, "" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
|
std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filetype ) const
|
const std::string &filetype ) const {
|
||||||
{
|
|
||||||
std::vector< Result > results;
|
std::vector< Result > results;
|
||||||
ResultsForQueryAndType( query, filetype, results );
|
ResultsForQueryAndType( query, filetype, results );
|
||||||
|
|
||||||
std::vector< std::string > candidates;
|
std::vector< std::string > candidates;
|
||||||
candidates.reserve( results.size() );
|
candidates.reserve( results.size() );
|
||||||
|
|
||||||
foreach ( const Result& result, results )
|
foreach ( const Result & result, results ) {
|
||||||
{
|
|
||||||
candidates.push_back( *result.Text() );
|
candidates.push_back( *result.Text() );
|
||||||
}
|
}
|
||||||
return candidates;
|
return candidates;
|
||||||
@ -210,9 +187,8 @@ std::vector< std::string > IdentifierCompleter::CandidatesForQueryAndType(
|
|||||||
|
|
||||||
|
|
||||||
Future< AsyncResults > IdentifierCompleter::CandidatesForQueryAndTypeAsync(
|
Future< AsyncResults > IdentifierCompleter::CandidatesForQueryAndTypeAsync(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filetype ) const
|
const std::string &filetype ) const {
|
||||||
{
|
|
||||||
// TODO: throw exception when threading is not enabled and this is called
|
// TODO: throw exception when threading is not enabled and this is called
|
||||||
if ( !threading_enabled_ )
|
if ( !threading_enabled_ )
|
||||||
return Future< AsyncResults >();
|
return Future< AsyncResults >();
|
||||||
@ -224,8 +200,8 @@ Future< AsyncResults > IdentifierCompleter::CandidatesForQueryAndTypeAsync(
|
|||||||
filetype );
|
filetype );
|
||||||
|
|
||||||
QueryTask task = make_shared< packaged_task< AsyncResults > >(
|
QueryTask task = make_shared< packaged_task< AsyncResults > >(
|
||||||
bind( ReturnValueAsShared< std::vector< std::string > >,
|
bind( ReturnValueAsShared< std::vector< std::string > >,
|
||||||
functor ) );
|
functor ) );
|
||||||
|
|
||||||
unique_future< AsyncResults > future = task->get_future();
|
unique_future< AsyncResults > future = task->get_future();
|
||||||
|
|
||||||
@ -235,24 +211,22 @@ Future< AsyncResults > IdentifierCompleter::CandidatesForQueryAndTypeAsync(
|
|||||||
|
|
||||||
|
|
||||||
void IdentifierCompleter::ResultsForQueryAndType(
|
void IdentifierCompleter::ResultsForQueryAndType(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
std::vector< Result > &results ) const
|
std::vector< Result > &results ) const {
|
||||||
{
|
|
||||||
FiletypeMap::const_iterator it = filetype_map_.find( filetype );
|
FiletypeMap::const_iterator it = filetype_map_.find( filetype );
|
||||||
|
|
||||||
if ( it == filetype_map_.end() || query.empty() )
|
if ( it == filetype_map_.end() || query.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Bitset query_bitset = LetterBitsetFromString( query );
|
Bitset query_bitset = LetterBitsetFromString( query );
|
||||||
|
|
||||||
boost::unordered_set< const Candidate* > seen_candidates;
|
boost::unordered_set< const Candidate * > seen_candidates;
|
||||||
seen_candidates.reserve( candidate_repository_.NumStoredCandidates() );
|
seen_candidates.reserve( candidate_repository_.NumStoredCandidates() );
|
||||||
|
|
||||||
foreach ( const FilepathToCandidates::value_type &path_and_candidates,
|
foreach ( const FilepathToCandidates::value_type & path_and_candidates,
|
||||||
*it->second )
|
*it->second ) {
|
||||||
{
|
foreach ( const Candidate * candidate, *path_and_candidates.second ) {
|
||||||
foreach ( const Candidate* candidate, *path_and_candidates.second )
|
|
||||||
{
|
|
||||||
if ( ContainsKey( seen_candidates, candidate ) )
|
if ( ContainsKey( seen_candidates, candidate ) )
|
||||||
continue;
|
continue;
|
||||||
else
|
else
|
||||||
@ -262,6 +236,7 @@ void IdentifierCompleter::ResultsForQueryAndType(
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
Result result = candidate->QueryMatchResult( query );
|
Result result = candidate->QueryMatchResult( query );
|
||||||
|
|
||||||
if ( result.IsSubsequence() )
|
if ( result.IsSubsequence() )
|
||||||
results.push_back( result );
|
results.push_back( result );
|
||||||
}
|
}
|
||||||
@ -272,48 +247,44 @@ void IdentifierCompleter::ResultsForQueryAndType(
|
|||||||
|
|
||||||
|
|
||||||
void IdentifierCompleter::ClearCandidatesStoredForFile(
|
void IdentifierCompleter::ClearCandidatesStoredForFile(
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath )
|
const std::string &filepath ) {
|
||||||
{
|
|
||||||
GetCandidateList( filetype, filepath ).clear();
|
GetCandidateList( filetype, filepath ).clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::list< const Candidate* >& IdentifierCompleter::GetCandidateList(
|
std::list< const Candidate * > &IdentifierCompleter::GetCandidateList(
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath )
|
const std::string &filepath ) {
|
||||||
{
|
|
||||||
boost::shared_ptr< FilepathToCandidates > &path_to_candidates =
|
boost::shared_ptr< FilepathToCandidates > &path_to_candidates =
|
||||||
filetype_map_[ filetype ];
|
filetype_map_[ filetype ];
|
||||||
|
|
||||||
if ( !path_to_candidates )
|
if ( !path_to_candidates )
|
||||||
path_to_candidates.reset( new FilepathToCandidates() );
|
path_to_candidates.reset( new FilepathToCandidates() );
|
||||||
|
|
||||||
boost::shared_ptr< std::list< const Candidate* > > &candidates =
|
boost::shared_ptr< std::list< const Candidate * > > &candidates =
|
||||||
(*path_to_candidates)[ filepath ];
|
( *path_to_candidates )[ filepath ];
|
||||||
|
|
||||||
if ( !candidates )
|
if ( !candidates )
|
||||||
candidates.reset( new std::list< const Candidate* >() );
|
candidates.reset( new std::list< const Candidate * >() );
|
||||||
|
|
||||||
return *candidates;
|
return *candidates;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IdentifierCompleter::InitThreads()
|
void IdentifierCompleter::InitThreads() {
|
||||||
{
|
|
||||||
int query_threads_to_create =
|
int query_threads_to_create =
|
||||||
std::max( MIN_ASYNC_THREADS,
|
std::max( MIN_ASYNC_THREADS,
|
||||||
std::min( MAX_ASYNC_THREADS, thread::hardware_concurrency() ) );
|
std::min( MAX_ASYNC_THREADS, thread::hardware_concurrency() ) );
|
||||||
|
|
||||||
for ( int i = 0; i < query_threads_to_create; ++i )
|
for ( int i = 0; i < query_threads_to_create; ++i ) {
|
||||||
{
|
|
||||||
query_threads_.create_thread( bind( QueryThreadMain,
|
query_threads_.create_thread( bind( QueryThreadMain,
|
||||||
boost::ref( latest_query_task_ ) ) );
|
boost::ref( latest_query_task_ ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_identifiers_thread_ = boost::thread(
|
buffer_identifiers_thread_ = boost::thread(
|
||||||
BufferIdentifiersThreadMain,
|
BufferIdentifiersThreadMain,
|
||||||
boost::ref( buffer_identifiers_task_stack_ ) );
|
boost::ref( buffer_identifiers_task_stack_ ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class Candidate;
|
class Candidate;
|
||||||
class CandidateRepository;
|
class CandidateRepository;
|
||||||
@ -39,23 +38,22 @@ class CandidateRepository;
|
|||||||
typedef boost::shared_ptr< std::vector< std::string > > AsyncResults;
|
typedef boost::shared_ptr< std::vector< std::string > > AsyncResults;
|
||||||
|
|
||||||
|
|
||||||
class IdentifierCompleter : boost::noncopyable
|
class IdentifierCompleter : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
IdentifierCompleter();
|
IdentifierCompleter();
|
||||||
IdentifierCompleter( const std::vector< std::string > &candidates );
|
IdentifierCompleter( const std::vector< std::string > &candidates );
|
||||||
IdentifierCompleter( const std::vector< std::string > &candidates,
|
IdentifierCompleter( const std::vector< std::string > &candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
|
|
||||||
~IdentifierCompleter();
|
~IdentifierCompleter();
|
||||||
|
|
||||||
void EnableThreading();
|
void EnableThreading();
|
||||||
|
|
||||||
void AddCandidatesToDatabase(
|
void AddCandidatesToDatabase(
|
||||||
const std::vector< std::string > &new_candidates,
|
const std::vector< std::string > &new_candidates,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
|
|
||||||
void AddCandidatesToDatabaseFromBuffer( const std::string &buffer_contents,
|
void AddCandidatesToDatabaseFromBuffer( const std::string &buffer_contents,
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
@ -65,24 +63,24 @@ public:
|
|||||||
// avoid an expensive copy of buffer_contents if the param is taken by value
|
// avoid an expensive copy of buffer_contents if the param is taken by value
|
||||||
// (move ctors FTW)
|
// (move ctors FTW)
|
||||||
void AddCandidatesToDatabaseFromBufferAsync(
|
void AddCandidatesToDatabaseFromBufferAsync(
|
||||||
std::string buffer_contents,
|
std::string buffer_contents,
|
||||||
std::string filetype,
|
std::string filetype,
|
||||||
std::string filepath );
|
std::string filepath );
|
||||||
|
|
||||||
// Only provided for tests!
|
// Only provided for tests!
|
||||||
std::vector< std::string > CandidatesForQuery(
|
std::vector< std::string > CandidatesForQuery(
|
||||||
const std::string &query ) const;
|
const std::string &query ) const;
|
||||||
|
|
||||||
std::vector< std::string > CandidatesForQueryAndType(
|
std::vector< std::string > CandidatesForQueryAndType(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filetype ) const;
|
const std::string &filetype ) const;
|
||||||
|
|
||||||
Future< AsyncResults > CandidatesForQueryAndTypeAsync(
|
Future< AsyncResults > CandidatesForQueryAndTypeAsync(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &filetype ) const;
|
const std::string &filetype ) const;
|
||||||
|
|
||||||
typedef boost::shared_ptr<
|
typedef boost::shared_ptr <
|
||||||
boost::packaged_task< AsyncResults > > QueryTask;
|
boost::packaged_task< AsyncResults > > QueryTask;
|
||||||
|
|
||||||
typedef ConcurrentLatestValue< QueryTask > LatestQueryTask;
|
typedef ConcurrentLatestValue< QueryTask > LatestQueryTask;
|
||||||
|
|
||||||
@ -97,21 +95,21 @@ private:
|
|||||||
void ClearCandidatesStoredForFile( const std::string &filetype,
|
void ClearCandidatesStoredForFile( const std::string &filetype,
|
||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
|
|
||||||
std::list< const Candidate* >& GetCandidateList(
|
std::list< const Candidate * > &GetCandidateList(
|
||||||
const std::string &filetype,
|
const std::string &filetype,
|
||||||
const std::string &filepath );
|
const std::string &filepath );
|
||||||
|
|
||||||
void InitThreads();
|
void InitThreads();
|
||||||
|
|
||||||
|
|
||||||
// filepath -> *( *candidate )
|
// filepath -> *( *candidate )
|
||||||
typedef boost::unordered_map< std::string,
|
typedef boost::unordered_map < std::string,
|
||||||
boost::shared_ptr< std::list< const Candidate* > > >
|
boost::shared_ptr< std::list< const Candidate * > > >
|
||||||
FilepathToCandidates;
|
FilepathToCandidates;
|
||||||
|
|
||||||
// filetype -> *( filepath -> *( *candidate ) )
|
// filetype -> *( filepath -> *( *candidate ) )
|
||||||
typedef boost::unordered_map< std::string,
|
typedef boost::unordered_map < std::string,
|
||||||
boost::shared_ptr< FilepathToCandidates > > FiletypeMap;
|
boost::shared_ptr< FilepathToCandidates > > FiletypeMap;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,10 +21,9 @@
|
|||||||
#include <boost/regex.hpp>
|
#include <boost/regex.hpp>
|
||||||
#include <boost/algorithm/string/regex.hpp>
|
#include <boost/algorithm/string/regex.hpp>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
const char* COMMENT_AND_STRING_REGEX =
|
const char *COMMENT_AND_STRING_REGEX =
|
||||||
"//.*?$" // Anything following '//'
|
"//.*?$" // Anything following '//'
|
||||||
"|"
|
"|"
|
||||||
"#.*?$" // Anything following '#'
|
"#.*?$" // Anything following '#'
|
||||||
@ -35,19 +34,17 @@ const char* COMMENT_AND_STRING_REGEX =
|
|||||||
"|"
|
"|"
|
||||||
"\"[^\"]*\""; // Anything inside double quotes, "..."
|
"\"[^\"]*\""; // Anything inside double quotes, "..."
|
||||||
|
|
||||||
const char* IDENTIFIER_REGEX = "[_a-zA-Z]\\w*";
|
const char *IDENTIFIER_REGEX = "[_a-zA-Z]\\w*";
|
||||||
|
|
||||||
|
|
||||||
std::string RemoveIdentifierFreeText( std::string text )
|
std::string RemoveIdentifierFreeText( std::string text ) {
|
||||||
{
|
|
||||||
boost::erase_all_regex( text, boost::regex( COMMENT_AND_STRING_REGEX ) );
|
boost::erase_all_regex( text, boost::regex( COMMENT_AND_STRING_REGEX ) );
|
||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector< std::string > ExtractIdentifiersFromText(
|
std::vector< std::string > ExtractIdentifiersFromText(
|
||||||
const std::string &text )
|
const std::string &text ) {
|
||||||
{
|
|
||||||
std::string::const_iterator start = text.begin();
|
std::string::const_iterator start = text.begin();
|
||||||
std::string::const_iterator end = text.end();
|
std::string::const_iterator end = text.end();
|
||||||
|
|
||||||
@ -55,8 +52,8 @@ std::vector< std::string > ExtractIdentifiersFromText(
|
|||||||
boost::regex expression( IDENTIFIER_REGEX );
|
boost::regex expression( IDENTIFIER_REGEX );
|
||||||
|
|
||||||
std::vector< std::string > identifiers;
|
std::vector< std::string > identifiers;
|
||||||
while ( boost::regex_search( start, end, matches, expression ) )
|
|
||||||
{
|
while ( boost::regex_search( start, end, matches, expression ) ) {
|
||||||
identifiers.push_back( matches[ 0 ] );
|
identifiers.push_back( matches[ 0 ] );
|
||||||
start = matches[ 0 ].second;
|
start = matches[ 0 ].second;
|
||||||
}
|
}
|
||||||
|
@ -21,8 +21,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
// NOTE: this function accepts the text param by value on purpose; it internally
|
// NOTE: this function accepts the text param by value on purpose; it internally
|
||||||
// needs a copy before processing the text so the copy might as well be made on
|
// needs a copy before processing the text so the copy might as well be made on
|
||||||
@ -32,7 +31,7 @@ namespace YouCompleteMe
|
|||||||
std::string RemoveIdentifierFreeText( std::string text );
|
std::string RemoveIdentifierFreeText( std::string text );
|
||||||
|
|
||||||
std::vector< std::string > ExtractIdentifiersFromText(
|
std::vector< std::string > ExtractIdentifiersFromText(
|
||||||
const std::string &text );
|
const std::string &text );
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
|
||||||
|
@ -19,14 +19,12 @@
|
|||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
|
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
LetterNode::LetterNode( char letter, int index )
|
LetterNode::LetterNode( char letter, int index )
|
||||||
: is_uppercase_( IsUppercase( letter ) ),
|
: is_uppercase_( IsUppercase( letter ) ),
|
||||||
is_root_node_( false ),
|
is_root_node_( false ),
|
||||||
index_( index )
|
index_( index ) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -34,12 +32,10 @@ LetterNode::LetterNode( char letter, int index )
|
|||||||
LetterNode::LetterNode( const std::string &text )
|
LetterNode::LetterNode( const std::string &text )
|
||||||
: is_uppercase_( false ),
|
: is_uppercase_( false ),
|
||||||
is_root_node_( true ),
|
is_root_node_( true ),
|
||||||
index_( -1 )
|
index_( -1 ) {
|
||||||
{
|
|
||||||
letternode_per_text_index_.resize( text.size() );
|
letternode_per_text_index_.resize( text.size() );
|
||||||
|
|
||||||
for ( uint i = 0; i < text.size(); ++i)
|
for ( uint i = 0; i < text.size(); ++i ) {
|
||||||
{
|
|
||||||
char letter = text[ i ];
|
char letter = text[ i ];
|
||||||
LetterNode *node = new LetterNode( letter, i );
|
LetterNode *node = new LetterNode( letter, i );
|
||||||
letters_[ letter ].push_back( node );
|
letters_[ letter ].push_back( node );
|
||||||
@ -47,12 +43,10 @@ LetterNode::LetterNode( const std::string &text )
|
|||||||
}
|
}
|
||||||
|
|
||||||
for ( int i = static_cast< int >( letternode_per_text_index_.size() ) - 1;
|
for ( int i = static_cast< int >( letternode_per_text_index_.size() ) - 1;
|
||||||
i >= 0; --i )
|
i >= 0; --i ) {
|
||||||
{
|
|
||||||
LetterNode *node_to_add = letternode_per_text_index_[ i ].get();
|
LetterNode *node_to_add = letternode_per_text_index_[ i ].get();
|
||||||
|
|
||||||
for ( int j = i - 1; j >= 0; --j )
|
for ( int j = i - 1; j >= 0; --j ) {
|
||||||
{
|
|
||||||
letternode_per_text_index_[ j ]->PrependNodeForLetter( text[ i ],
|
letternode_per_text_index_[ j ]->PrependNodeForLetter( text[ i ],
|
||||||
node_to_add );
|
node_to_add );
|
||||||
}
|
}
|
||||||
|
@ -28,36 +28,30 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class LetterNode : boost::noncopyable
|
class LetterNode : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
explicit LetterNode( char letter, int index );
|
explicit LetterNode( char letter, int index );
|
||||||
|
|
||||||
// this is for root nodes
|
// this is for root nodes
|
||||||
explicit LetterNode( const std::string &text );
|
explicit LetterNode( const std::string &text );
|
||||||
|
|
||||||
inline bool LetterIsUppercase() const
|
inline bool LetterIsUppercase() const {
|
||||||
{
|
|
||||||
return is_uppercase_;
|
return is_uppercase_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline const std::list< LetterNode* >* NodeListForLetter( char letter )
|
inline const std::list< LetterNode * > *NodeListForLetter( char letter ) {
|
||||||
{
|
|
||||||
return letters_.ListPointerAt( letter );
|
return letters_.ListPointerAt( letter );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void PrependNodeForLetter( char letter, LetterNode* node )
|
inline void PrependNodeForLetter( char letter, LetterNode *node ) {
|
||||||
{
|
|
||||||
letters_[ letter ].push_front( node );
|
letters_[ letter ].push_front( node );
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int Index()
|
inline int Index() {
|
||||||
{
|
|
||||||
return index_;
|
return index_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,9 +59,9 @@ private:
|
|||||||
|
|
||||||
LetterNodeListMap letters_;
|
LetterNodeListMap letters_;
|
||||||
std::vector< boost::shared_ptr< LetterNode > > letternode_per_text_index_;
|
std::vector< boost::shared_ptr< LetterNode > > letternode_per_text_index_;
|
||||||
bool is_uppercase_;
|
bool is_uppercase_;
|
||||||
bool is_root_node_;
|
bool is_root_node_;
|
||||||
int index_;
|
int index_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
@ -18,22 +18,19 @@
|
|||||||
#include "LetterNodeListMap.h"
|
#include "LetterNodeListMap.h"
|
||||||
#include "standard.h"
|
#include "standard.h"
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
const int kNumLetters = NUM_LETTERS;
|
const int kNumLetters = NUM_LETTERS;
|
||||||
static const int kLettersIndexStart = 0;
|
static const int kLettersIndexStart = 0;
|
||||||
static const int kNumbersIndexStart = 26;
|
static const int kNumbersIndexStart = 26;
|
||||||
|
|
||||||
|
|
||||||
bool IsUppercase( char letter )
|
bool IsUppercase( char letter ) {
|
||||||
{
|
|
||||||
return 'A' <= letter && letter <= 'Z';
|
return 'A' <= letter && letter <= 'Z';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int IndexForChar( char letter )
|
int IndexForChar( char letter ) {
|
||||||
{
|
|
||||||
if ( IsUppercase( letter ) )
|
if ( IsUppercase( letter ) )
|
||||||
return letter + ( 'a' - 'A' );
|
return letter + ( 'a' - 'A' );
|
||||||
|
|
||||||
@ -41,55 +38,48 @@ int IndexForChar( char letter )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LetterNodeListMap::LetterNodeListMap()
|
LetterNodeListMap::LetterNodeListMap() {
|
||||||
{
|
|
||||||
letters_.resize( kNumLetters );
|
letters_.resize( kNumLetters );
|
||||||
|
|
||||||
for ( uint i = 0; i < letters_.size(); ++i )
|
for ( uint i = 0; i < letters_.size(); ++i ) {
|
||||||
{
|
|
||||||
letters_[ i ] = NULL;
|
letters_[ i ] = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
LetterNodeListMap::~LetterNodeListMap()
|
LetterNodeListMap::~LetterNodeListMap() {
|
||||||
{
|
for ( uint i = 0; i < letters_.size(); ++i ) {
|
||||||
for ( uint i = 0; i < letters_.size(); ++i )
|
|
||||||
{
|
|
||||||
delete letters_[ i ];
|
delete letters_[ i ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LetterNodeListMap::HasLetter( char letter )
|
bool LetterNodeListMap::HasLetter( char letter ) {
|
||||||
{
|
|
||||||
int letter_index = IndexForChar( letter );
|
int letter_index = IndexForChar( letter );
|
||||||
std::list< LetterNode* > *list = letters_[ letter_index ];
|
std::list< LetterNode * > *list = letters_[ letter_index ];
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::list< LetterNode* >& LetterNodeListMap::operator[] ( char letter )
|
std::list< LetterNode * > &LetterNodeListMap::operator[] ( char letter ) {
|
||||||
{
|
|
||||||
int letter_index = IndexForChar( letter );
|
int letter_index = IndexForChar( letter );
|
||||||
std::list< LetterNode* > *list = letters_[ letter_index ];
|
std::list< LetterNode * > *list = letters_[ letter_index ];
|
||||||
|
|
||||||
if ( list )
|
if ( list )
|
||||||
|
|
||||||
return *list;
|
return *list;
|
||||||
|
|
||||||
letters_[ letter_index ] = new std::list< LetterNode* >();
|
letters_[ letter_index ] = new std::list< LetterNode * >();
|
||||||
return *letters_[ letter_index ];
|
return *letters_[ letter_index ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::list< LetterNode* >* LetterNodeListMap::ListPointerAt( char letter )
|
std::list< LetterNode * > *LetterNodeListMap::ListPointerAt( char letter ) {
|
||||||
{
|
|
||||||
return letters_[ IndexForChar( letter ) ];
|
return letters_[ IndexForChar( letter ) ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool LetterNodeListMap::HasLetter( char letter ) const
|
bool LetterNodeListMap::HasLetter( char letter ) const {
|
||||||
{
|
|
||||||
return letters_[ IndexForChar( letter ) ] != NULL;
|
return letters_[ IndexForChar( letter ) ] != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,8 +24,7 @@
|
|||||||
|
|
||||||
#define NUM_LETTERS 128
|
#define NUM_LETTERS 128
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class LetterNode;
|
class LetterNode;
|
||||||
|
|
||||||
@ -34,23 +33,22 @@ extern const int kNumLetters;
|
|||||||
int IndexForChar( char letter );
|
int IndexForChar( char letter );
|
||||||
bool IsUppercase( char letter );
|
bool IsUppercase( char letter );
|
||||||
|
|
||||||
class LetterNodeListMap : boost::noncopyable
|
class LetterNodeListMap : boost::noncopyable {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
LetterNodeListMap();
|
LetterNodeListMap();
|
||||||
~LetterNodeListMap();
|
~LetterNodeListMap();
|
||||||
|
|
||||||
bool HasLetter( char letter );
|
bool HasLetter( char letter );
|
||||||
|
|
||||||
std::list< LetterNode* >& operator[] ( char letter );
|
std::list< LetterNode * > &operator[] ( char letter );
|
||||||
|
|
||||||
std::list< LetterNode* >* ListPointerAt( char letter );
|
std::list< LetterNode * > *ListPointerAt( char letter );
|
||||||
|
|
||||||
bool HasLetter( char letter ) const;
|
bool HasLetter( char letter ) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
std::vector< std::list< LetterNode* >* > letters_;
|
std::vector< std::list< LetterNode * >* > letters_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace YouCompleteMe
|
} // namespace YouCompleteMe
|
||||||
|
@ -23,15 +23,12 @@
|
|||||||
|
|
||||||
using boost::algorithm::istarts_with;
|
using boost::algorithm::istarts_with;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
namespace
|
namespace {
|
||||||
{
|
|
||||||
|
|
||||||
int LongestCommonSubsequenceLength( const std::string &first,
|
int LongestCommonSubsequenceLength( const std::string &first,
|
||||||
const std::string &second )
|
const std::string &second ) {
|
||||||
{
|
|
||||||
const std::string &longer = first.size() > second.size() ? first : second;
|
const std::string &longer = first.size() > second.size() ? first : second;
|
||||||
const std::string &shorter = first.size() > second.size() ? second : first;
|
const std::string &shorter = first.size() > second.size() ? second : first;
|
||||||
|
|
||||||
@ -41,18 +38,15 @@ int LongestCommonSubsequenceLength( const std::string &first,
|
|||||||
std::vector<int> previous( shorter_len + 1, 0 );
|
std::vector<int> previous( shorter_len + 1, 0 );
|
||||||
std::vector<int> current( shorter_len + 1, 0 );
|
std::vector<int> current( shorter_len + 1, 0 );
|
||||||
|
|
||||||
for (int i = 0; i < longer_len; ++i )
|
for ( int i = 0; i < longer_len; ++i ) {
|
||||||
{
|
for ( int j = 0; j < shorter_len; ++j ) {
|
||||||
for (int j = 0; j < shorter_len; ++j )
|
|
||||||
{
|
|
||||||
if ( toupper( longer[ i ] ) == toupper( shorter[ j ] ) )
|
if ( toupper( longer[ i ] ) == toupper( shorter[ j ] ) )
|
||||||
current[ j + 1 ] = previous[ j ] + 1;
|
current[ j + 1 ] = previous[ j ] + 1;
|
||||||
else
|
else
|
||||||
current[ j + 1 ] = std::max( current[ j ], previous[ j + 1 ] );
|
current[ j + 1 ] = std::max( current[ j ], previous[ j + 1 ] );
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < shorter_len; ++j )
|
for ( int j = 0; j < shorter_len; ++j ) {
|
||||||
{
|
|
||||||
previous[ j + 1 ] = current[ j + 1 ];
|
previous[ j + 1 ] = current[ j + 1 ];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -62,9 +56,8 @@ int LongestCommonSubsequenceLength( const std::string &first,
|
|||||||
|
|
||||||
|
|
||||||
int NumWordBoundaryCharMatches( const std::string &query,
|
int NumWordBoundaryCharMatches( const std::string &query,
|
||||||
const std::string &word_boundary_chars )
|
const std::string &word_boundary_chars ) {
|
||||||
{
|
return LongestCommonSubsequenceLength( query, word_boundary_chars );
|
||||||
return LongestCommonSubsequenceLength(query, word_boundary_chars);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // unnamed namespace
|
} // unnamed namespace
|
||||||
@ -79,8 +72,7 @@ Result::Result()
|
|||||||
query_is_candidate_prefix_( false ),
|
query_is_candidate_prefix_( false ),
|
||||||
text_is_lowercase_( false ),
|
text_is_lowercase_( false ),
|
||||||
char_match_index_sum_( 0 ),
|
char_match_index_sum_( 0 ),
|
||||||
text_( NULL )
|
text_( NULL ) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -94,8 +86,7 @@ Result::Result( bool is_subsequence )
|
|||||||
query_is_candidate_prefix_( false ),
|
query_is_candidate_prefix_( false ),
|
||||||
text_is_lowercase_( false ),
|
text_is_lowercase_( false ),
|
||||||
char_match_index_sum_( 0 ),
|
char_match_index_sum_( 0 ),
|
||||||
text_( NULL )
|
text_( NULL ) {
|
||||||
{
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -114,66 +105,57 @@ Result::Result( bool is_subsequence,
|
|||||||
query_is_candidate_prefix_( false ),
|
query_is_candidate_prefix_( false ),
|
||||||
text_is_lowercase_( text_is_lowercase ),
|
text_is_lowercase_( text_is_lowercase ),
|
||||||
char_match_index_sum_( char_match_index_sum ),
|
char_match_index_sum_( char_match_index_sum ),
|
||||||
text_( text )
|
text_( text ) {
|
||||||
{
|
|
||||||
if ( is_subsequence )
|
if ( is_subsequence )
|
||||||
SetResultFeaturesFromQuery( word_boundary_chars, query );
|
SetResultFeaturesFromQuery( word_boundary_chars, query );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Result::operator< ( const Result &other ) const
|
bool Result::operator< ( const Result &other ) const {
|
||||||
{
|
|
||||||
// Yes, this is ugly but it also needs to be fast. Since this is called a
|
// Yes, this is ugly but it also needs to be fast. Since this is called a
|
||||||
// bazillion times, we have to make sure only the required comparisons are
|
// bazillion times, we have to make sure only the required comparisons are
|
||||||
// made, and no more.
|
// made, and no more.
|
||||||
|
|
||||||
if ( !query_is_empty_ )
|
if ( !query_is_empty_ ) {
|
||||||
{
|
|
||||||
if ( first_char_same_in_query_and_text_ !=
|
if ( first_char_same_in_query_and_text_ !=
|
||||||
other.first_char_same_in_query_and_text_ )
|
other.first_char_same_in_query_and_text_ ) {
|
||||||
{
|
|
||||||
return first_char_same_in_query_and_text_;
|
return first_char_same_in_query_and_text_;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool equal_wb_ratios = AlmostEqual(
|
bool equal_wb_ratios = AlmostEqual(
|
||||||
ratio_of_word_boundary_chars_in_query_,
|
ratio_of_word_boundary_chars_in_query_,
|
||||||
other.ratio_of_word_boundary_chars_in_query_ );
|
other.ratio_of_word_boundary_chars_in_query_ );
|
||||||
|
|
||||||
bool equal_wb_utilization = AlmostEqual(
|
bool equal_wb_utilization = AlmostEqual(
|
||||||
word_boundary_char_utilization_,
|
word_boundary_char_utilization_,
|
||||||
other.word_boundary_char_utilization_ );
|
other.word_boundary_char_utilization_ );
|
||||||
|
|
||||||
if ( AlmostEqual( ratio_of_word_boundary_chars_in_query_, 1.0 ) ||
|
if ( AlmostEqual( ratio_of_word_boundary_chars_in_query_, 1.0 ) ||
|
||||||
AlmostEqual( other.ratio_of_word_boundary_chars_in_query_, 1.0 ) )
|
AlmostEqual( other.ratio_of_word_boundary_chars_in_query_, 1.0 ) ) {
|
||||||
{
|
if ( !equal_wb_ratios ) {
|
||||||
if ( !equal_wb_ratios )
|
|
||||||
{
|
|
||||||
return ratio_of_word_boundary_chars_in_query_ >
|
return ratio_of_word_boundary_chars_in_query_ >
|
||||||
other.ratio_of_word_boundary_chars_in_query_;
|
other.ratio_of_word_boundary_chars_in_query_;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if ( !equal_wb_utilization )
|
if ( !equal_wb_utilization )
|
||||||
return word_boundary_char_utilization_ >
|
return word_boundary_char_utilization_ >
|
||||||
other.word_boundary_char_utilization_;
|
other.word_boundary_char_utilization_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( query_is_candidate_prefix_ != other.query_is_candidate_prefix_ )
|
if ( query_is_candidate_prefix_ != other.query_is_candidate_prefix_ )
|
||||||
return query_is_candidate_prefix_;
|
return query_is_candidate_prefix_;
|
||||||
|
|
||||||
if ( !equal_wb_ratios )
|
if ( !equal_wb_ratios ) {
|
||||||
{
|
|
||||||
return ratio_of_word_boundary_chars_in_query_ >
|
return ratio_of_word_boundary_chars_in_query_ >
|
||||||
other.ratio_of_word_boundary_chars_in_query_;
|
other.ratio_of_word_boundary_chars_in_query_;
|
||||||
}
|
}
|
||||||
|
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
if ( !equal_wb_utilization )
|
if ( !equal_wb_utilization )
|
||||||
return word_boundary_char_utilization_ >
|
return word_boundary_char_utilization_ >
|
||||||
other.word_boundary_char_utilization_;
|
other.word_boundary_char_utilization_;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( char_match_index_sum_ != other.char_match_index_sum_ )
|
if ( char_match_index_sum_ != other.char_match_index_sum_ )
|
||||||
@ -192,16 +174,15 @@ bool Result::operator< ( const Result &other ) const
|
|||||||
|
|
||||||
|
|
||||||
void Result::SetResultFeaturesFromQuery(
|
void Result::SetResultFeaturesFromQuery(
|
||||||
const std::string &word_boundary_chars,
|
const std::string &word_boundary_chars,
|
||||||
const std::string &query)
|
const std::string &query ) {
|
||||||
{
|
|
||||||
query_is_empty_ = query.empty();
|
query_is_empty_ = query.empty();
|
||||||
|
|
||||||
if ( query.empty() || text_->empty() )
|
if ( query.empty() || text_->empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
first_char_same_in_query_and_text_ =
|
first_char_same_in_query_and_text_ =
|
||||||
toupper( query[ 0 ] ) == toupper( (*text_)[ 0 ] );
|
toupper( query[ 0 ] ) == toupper( ( *text_ )[ 0 ] );
|
||||||
int num_wb_matches = NumWordBoundaryCharMatches( query,
|
int num_wb_matches = NumWordBoundaryCharMatches( query,
|
||||||
word_boundary_chars );
|
word_boundary_chars );
|
||||||
ratio_of_word_boundary_chars_in_query_ =
|
ratio_of_word_boundary_chars_in_query_ =
|
||||||
|
@ -20,11 +20,9 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
class Result
|
class Result {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
Result();
|
Result();
|
||||||
explicit Result( bool is_subsequence );
|
explicit Result( bool is_subsequence );
|
||||||
@ -38,20 +36,18 @@ public:
|
|||||||
|
|
||||||
bool operator< ( const Result &other ) const;
|
bool operator< ( const Result &other ) const;
|
||||||
|
|
||||||
inline bool IsSubsequence() const
|
inline bool IsSubsequence() const {
|
||||||
{
|
|
||||||
return is_subsequence_;
|
return is_subsequence_;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const std::string* Text() const
|
inline const std::string *Text() const {
|
||||||
{
|
|
||||||
return text_;
|
return text_;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void SetResultFeaturesFromQuery(
|
void SetResultFeaturesFromQuery(
|
||||||
const std::string &query,
|
const std::string &query,
|
||||||
const std::string &word_boundary_chars );
|
const std::string &word_boundary_chars );
|
||||||
|
|
||||||
// true when the query for which the result was created was an empty string;
|
// true when the query for which the result was created was an empty string;
|
||||||
// in these cases we just use a lexicographic comparison
|
// in these cases we just use a lexicographic comparison
|
||||||
|
@ -23,32 +23,28 @@
|
|||||||
|
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
bool AlmostEqual( double a, double b )
|
bool AlmostEqual( double a, double b ) {
|
||||||
{
|
|
||||||
return std::abs( a - b ) <=
|
return std::abs( a - b ) <=
|
||||||
( std::numeric_limits< double >::epsilon() *
|
( std::numeric_limits< double >::epsilon() *
|
||||||
std::max( std::abs( a ), std::abs( b ) ) );
|
std::max( std::abs( a ), std::abs( b ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string ReadUtf8File( const fs::path &filepath )
|
std::string ReadUtf8File( const fs::path &filepath ) {
|
||||||
{
|
fs::ifstream file( filepath, std::ios::in | std::ios::binary );
|
||||||
fs::ifstream file( filepath, std::ios::in | std::ios::binary );
|
std::vector< char > contents( ( std::istreambuf_iterator< char >( file ) ),
|
||||||
std::vector< char > contents( (std::istreambuf_iterator< char >( file )),
|
std::istreambuf_iterator< char >() );
|
||||||
std::istreambuf_iterator< char >() );
|
|
||||||
|
|
||||||
if ( contents.size() == 0 )
|
if ( contents.size() == 0 )
|
||||||
return std::string();
|
return std::string();
|
||||||
|
|
||||||
return std::string( contents.begin(), contents.end() );
|
return std::string( contents.begin(), contents.end() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void WriteUtf8File( const fs::path &filepath, const std::string &contents )
|
void WriteUtf8File( const fs::path &filepath, const std::string &contents ) {
|
||||||
{
|
|
||||||
fs::ofstream file;
|
fs::ofstream file;
|
||||||
file.open( filepath );
|
file.open( filepath );
|
||||||
file << contents;
|
file << contents;
|
||||||
|
@ -23,8 +23,7 @@
|
|||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
namespace fs = boost::filesystem;
|
namespace fs = boost::filesystem;
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
bool AlmostEqual( double a, double b );
|
bool AlmostEqual( double a, double b );
|
||||||
|
|
||||||
@ -40,16 +39,14 @@ template <class Container, class Key>
|
|||||||
typename Container::mapped_type &
|
typename Container::mapped_type &
|
||||||
GetValueElseInsert( Container &container,
|
GetValueElseInsert( Container &container,
|
||||||
const Key &key,
|
const Key &key,
|
||||||
const typename Container::mapped_type &value )
|
const typename Container::mapped_type &value ) {
|
||||||
{
|
|
||||||
return container.insert( typename Container::value_type( key, value ) )
|
return container.insert( typename Container::value_type( key, value ) )
|
||||||
.first->second;
|
.first->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Container, class Key>
|
template <class Container, class Key>
|
||||||
bool ContainsKey( Container &container, const Key &key )
|
bool ContainsKey( Container &container, const Key &key ) {
|
||||||
{
|
|
||||||
return container.find( key ) != container.end();
|
return container.find( key ) != container.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,22 +55,21 @@ template <class Container, class Key>
|
|||||||
typename Container::mapped_type
|
typename Container::mapped_type
|
||||||
FindWithDefault( Container &container,
|
FindWithDefault( Container &container,
|
||||||
const Key &key,
|
const Key &key,
|
||||||
const typename Container::mapped_type &value )
|
const typename Container::mapped_type &value ) {
|
||||||
{
|
|
||||||
typename Container::iterator it = container.find( key );
|
typename Container::iterator it = container.find( key );
|
||||||
return it != container.end() ? it->second : value;
|
return it != container.end() ? it->second : value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <class Container, class Key>
|
template <class Container, class Key>
|
||||||
bool Erase( Container &container, const Key &key )
|
bool Erase( Container &container, const Key &key ) {
|
||||||
{
|
|
||||||
typename Container::iterator it = container.find( key );
|
typename Container::iterator it = container.find( key );
|
||||||
if ( it != container.end() )
|
|
||||||
{
|
if ( it != container.end() ) {
|
||||||
container.erase( it );
|
container.erase( it );
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
#include <boost/exception/all.hpp>
|
#include <boost/exception/all.hpp>
|
||||||
|
|
||||||
namespace YouCompleteMe
|
namespace YouCompleteMe {
|
||||||
{
|
|
||||||
|
|
||||||
#define boost_throw(x) BOOST_THROW_EXCEPTION(x)
|
#define boost_throw(x) BOOST_THROW_EXCEPTION(x)
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user