SyntaxHighlighter

вторник, 5 июня 2012 г.

C++ библиотека базовых классов от Facebook

Компания Facebook  открыла C++11 библиотеку Folly.

https://github.com/facebook/folly

Folly (acronymed loosely after Facebook Open Source Library) is a library of C++11 components designed with practicality and efficiency in mind. It complements (as opposed to competing against) offerings such as Boost and of course std. In fact, we embark on defining our own component only when something we need is either not available, or does not meet the needed performance profile.

Код библиотеки заточен под производительность и эффективное использование памяти, например: есть аналоги std::string и std::vector - fbstring и fbvector.

В авторах числится сам Андрей Александреску.
Код заточен под GCC и новый стандарт C++, есть подозрение, что под VS не соберётся.

FBString

Собственная реализация строк. Особенности реализации:
- для строк меньше 23 символов размещаются на месте, не используя динамической памяти
- для строк от 24 до 255 символов, используется динамически выделяемая память. При копировании строк, копируется и внутреннее хранилище
- для всех остальных строк используется Copy-On-Write стратегия (потокобезопасность гарантируется)
- для выделения памяти используется malloc, allocator-ы не используются
- эффективный алгоритм поиск подстроки (Boyer-Moore algorithm)
 - нулевой символ в конце строке дописывается только при вызове методов c_str() и data(). Этим поведением можно управлять макросами:

FBSTRING_PERVERSE
FBSTRING_CONSERVATIVE


В коде обильно используются assert-ы для проверки различных инвариантов.
Используется вспомогательный внутренний класс для проверки ненарушения методом инварианта класса.
 
  struct Invariant;
  friend struct Invariant;
  struct Invariant {
#ifndef NDEBUG
    explicit Invariant(const basic_fbstring& s) : s_(s) {
      assert(s_.isSane());
    }
    ~Invariant() {
      assert(s_.isSane());
    }
  private:
    const basic_fbstring& s_;
#else
    explicit Invariant(const basic_fbstring&) {}
#endif
    Invariant& operator=(const Invariant&);
  };
 
 Использование (в начале метода):
    Invariant checker(*this);
    (void) checker;
 Таким образом инвариант будет проверен при входе и при выходе из метода.

Вспомогательная функция, для проверки входных параметров
   static void enforce(
      bool condition,
      void (*throw_exc)(const char*),
      const char* msg) {
    if (!condition) throw_exc(msg);
  }

Пример использования:
  void reserve(size_type res_arg = 0) {
    enforce(res_arg <= max_size(), std::__throw_length_error, "");
    store_.reserve(res_arg);
  }

Код интересный и познавательный, содержит различные приёмы и трюки.
Вот пример:

      // Layout is: Char* data_, size_t size_, size_t capacity_
      /*static_*/assert(sizeof(*this) == sizeof(Char*) + 2 * sizeof(size_t));
      /*static_*/assert(sizeof(Char*) == sizeof(size_t));
      // sizeof(size_t) must be a power of 2
      /*static_*/assert((sizeof(size_t) & (sizeof(size_t) - 1)) == 0);

      // If data is aligned, use fast word-wise copying. Otherwise,
      // use conservative memcpy.
      if (reinterpret_cast<size_t>(data) & (sizeof(size_t) - 1)) {
        fbstring_detail::pod_copy(data, data + size, small_);
      } else {
        // Copy one word (64 bits) at a time
        const size_t byteSize = size * sizeof(Char);
        if (byteSize > 2 * sizeof(size_t)) {
          // Copy three words
          ml_.capacity_ = reinterpret_cast<const size_t*>(data)[2];
          copyTwo:
          ml_.size_ = reinterpret_cast<const size_t*>(data)[1];
          copyOne:
          ml_.data_ = *reinterpret_cast<Char**>(const_cast<Char*>(data));
        } else if (byteSize > sizeof(size_t)) {
          // Copy two words
          goto copyTwo;
        } else if (size > 0) {
          // Copy one word
          goto copyOne;
        }
      }

Комментариев нет:

Отправить комментарий