C++ → Пути к файлам
Казалось бы — что может быть проще, чем работа с файлами в C++. Но отдельные личности поражают своей находчивостью в поиске наихудшего подхода.Не стоит делать так:
std::string filepath("C:\\тест");
std::ofstream file(filepath.c_str());Drupal → Городской портал Большого Сочи на Drupal
Добрый день, друзья!
В октябре сего года увидел свет Макс Портал. Этот проект задуман как городской портал Большого Сочи. На данный момент там есть новости (в том числе фоторепортажи и видеосюжеты) и каталог предприятий — «желтые страницы» города с привязкой к карте. В планах — множество полезных разделов: погода, афиша, веб-камеры, онлайн-приемные чиновников, поиск работы, недвижимость, туризм и т.д. Запуск раздела «Погода» запланирован на январь.
В работе сайта задействованы следующие модули: Quicktabs, Panels, Mini Panels, Workflow, Boost, Chaos Tools, Date, Calendar, Drupal Wiki, Modal Frame, Nodequeue, Taxonomy Filter, Taxonomy Image, Vote Up/Down, Yandex Map и так далее.
Будем признательны за ваши комментарии, советы и пожелания!
В октябре сего года увидел свет Макс Портал. Этот проект задуман как городской портал Большого Сочи. На данный момент там есть новости (в том числе фоторепортажи и видеосюжеты) и каталог предприятий — «желтые страницы» города с привязкой к карте. В планах — множество полезных разделов: погода, афиша, веб-камеры, онлайн-приемные чиновников, поиск работы, недвижимость, туризм и т.д. Запуск раздела «Погода» запланирован на январь.
В работе сайта задействованы следующие модули: Quicktabs, Panels, Mini Panels, Workflow, Boost, Chaos Tools, Date, Calendar, Drupal Wiki, Modal Frame, Nodequeue, Taxonomy Filter, Taxonomy Image, Vote Up/Down, Yandex Map и так далее.
Будем признательны за ваши комментарии, советы и пожелания!
C++ → Использование boost::variant для описания состояний модели
В моделях данных очень часто требуется хранить некоторые переключаемые состояния. Классический способ в С++ для этого — использование перечислимых типов enum.
Например, если у вас в программе пользователь может переключаться между двумя экранами, вы заводите enum screen { screen_one, screen_two }; и переменную screen cur_screen_. Отрисовщик должен получить у модели «текущий выбранный экран», и затем отрисовать его, запрашивая у модели дополнительные данные, относящиеся именно к этому экрану. Что-то вроде:
При использовании такой модели, программист может запрашивать данные, которые для текущего состояния совершенно не актуальны. Например, вызвать метод get_screen_two_elements() для получения списка элементов второго экрана, когда текущий экран — первый. Хорошей практикой является использование ассертов вида ASSERT(cur_screen_ == screen_one) в методах, зависимых от конкретного экрана. Это обеспечивает некоторый контроль времени выполнения.
Но есть способ обеспечить контроль времени компиляции и более явное разделение состояний с помощью boost::variant.
Например, если у вас в программе пользователь может переключаться между двумя экранами, вы заводите enum screen { screen_one, screen_two }; и переменную screen cur_screen_. Отрисовщик должен получить у модели «текущий выбранный экран», и затем отрисовать его, запрашивая у модели дополнительные данные, относящиеся именно к этому экрану. Что-то вроде:
switch (model.cur_screen())
{
case screen_one:
model.get_screen_one_elements();
...
case screen_two:
model.get_screen_two_elements();
...
}
При использовании такой модели, программист может запрашивать данные, которые для текущего состояния совершенно не актуальны. Например, вызвать метод get_screen_two_elements() для получения списка элементов второго экрана, когда текущий экран — первый. Хорошей практикой является использование ассертов вида ASSERT(cur_screen_ == screen_one) в методах, зависимых от конкретного экрана. Это обеспечивает некоторый контроль времени выполнения.
Но есть способ обеспечить контроль времени компиляции и более явное разделение состояний с помощью boost::variant.
C++ → speedtest.net via C++
Весь нижеприведенный код — выдержка из одного моего недавнего проекта, в рамках которого было необходимо определять скорость download и upload. Изобретать велосипед было неохота, посему возникло желание воспользоваться сервисом www.speedtest.net, как наиболее уважаемым и работоспособным из сервисов такого типа. Впрочем, как показала практика, он оказался вполне недружелюбным и некий велосипед таки пришлось изобрести.
Персональные блоги → [C++] Сравнение структур по набору полей
Вступление
Вероятно, всякий сталкивался с ситуацией, когда нужно написать operator== или operator< для своей структуры. Раньше я делал это как-то так:
struct data
{
unsigned int a_ ;
int b_ ;
int c_ ;
int d_ ;
} ;
bool operator<(const data & a1, const data & a2)
{
// Сравнение по a_, b_ и d_
if (a1.a_ != a2.a_)
return a1.a_ < a2.a_ ;
if (a1.b_ != a2.b_)
return a1.b_ < a2.b_ ;
return a1.d_ < a2.b_ ;
}
Копипаст меня удручал, но придумать ничего путного я не мог.
C++ → Планирование задач в сервере при помощи boost.task
Недавно на профильном ресурсе один программист задал вопрос: «Что использовать в сервере ММО для работы с потоками?». Программист склонялся к Intel TBB, но даже не к базовым примитивам, а к кастомному планированию задач (task scheduling). Ну нравится TBB — ну и ладно. А немного позже я увидел исходники сервера ММО другого программиста, который недавно начал переписываться его с нуля для улучшения архитектуры. И там было очень много велосипедов, которые писались самим программистом вместо того что бы использовать сторонние компоненты такие как boost (к примеру класы обертки над pthread-ом, и это в 2010 году, когда boost.thread уже почти в стандарте). Была там реализована и поддержка пула потоков с планировщиком задач. Тема эта мне очень интересна и я начал копать информацию о готовых решениях планировки задач (как в TBB) и нашел boost.task, про что и решил написать.
C++ → Практическое использование Boost.Spirit
Я заметил, у разработчиков совершенно полярное отношение к библиотеке Boost.Spirit: либо она им жутко не нравится, либо они фанатеют от нее. Конечно, описывать грамматику на C++ – занятие на любителя. Таким любителем оказался и я, когда познакомился со Спиритом. Хочу показать, как с помощью Спирита можно довольно просто решать повседневные задачи разбора текста.
На Спирите очень удобно писать маленькие парсеры «не отходя от кассы» – прямо в C++ коде. Вот например, как вы поступите если нужно распарсить строку вида «число-число», которая задает диапазон страниц для печати? На Спирите – одна строчка:
Более того – можно ненамного сложнее создавать и парсеры побольше. В качестве примера рассмотрю парсер мини-языка, который я делал для API Яндекс.Бара. Задача была такова: для облегчения загрузки плагинов в баре используется XML, который довольно избыточный сам по себе. Но зато XML легче грузить из Javascript-а, чем парсить произвольный формат (на JS пишутся расширения под FireFox, в том числе и Я.Бар).
Итак, что мне было нужно – имея на входе обычную инфиксную нотацию:
Простая задача – как два пальца
На Спирите очень удобно писать маленькие парсеры «не отходя от кассы» – прямо в C++ коде. Вот например, как вы поступите если нужно распарсить строку вида «число-число», которая задает диапазон страниц для печати? На Спирите – одна строчка:
bool ok = parse(First, Last, (uint_ >> L"-" >> uint_), MinMax) && (First == Last);
Посложнее…
Более того – можно ненамного сложнее создавать и парсеры побольше. В качестве примера рассмотрю парсер мини-языка, который я делал для API Яндекс.Бара. Задача была такова: для облегчения загрузки плагинов в баре используется XML, который довольно избыточный сам по себе. Но зато XML легче грузить из Javascript-а, чем парсить произвольный формат (на JS пишутся расширения под FireFox, в том числе и Я.Бар).
Итак, что мне было нужно – имея на входе обычную инфиксную нотацию:
C++ → DSL для boost::MPL, превращаем f(x) в f<x>::type
Краткое содержание статьи (для тех кто знаком с boost::mpl), typename опущены для ясности:
Под хабракатом есть немного пояснений :)
a = b; ==> typedef b a;
f(x) ==> f<x>::type
f(x) { return x*; } ==> template<typename x> struct x { typedef x* type; };
f()(x) ==> f::apply<x>::type
a[x] ==> mpl::at<a, x>::type
(x ? y : z) ==> mpl::if_<x, y, z>::type
switch (if_<x, y, z>) ==> *Уфф*, общая (default) и частичные специализации
{
case if_<bool_<false>, y, z>: return y;
default: return z;
}
Под хабракатом есть немного пояснений :)
C++ → Spirit. Спиритические сеансы
Каждый программист в глубине души желает написать свой калькуляторязык программирования, но, вспоминая, как противно было в институте писать полотна в полторы тысячи строк и отлаживать их, прячет глубины своей души подальше от клавиатуры.
Недавно вышел Boost 1.41, а с ним и Spirit 2, синтаксический анализатор, почти равный по возможностям оригинальным регулярным выражениям Perl. Я просто обязан о нём написать.
Сегодня мы попытаемся запрограммировать простой интерпретируемый язык.
Недавно вышел Boost 1.41, а с ним и Spirit 2, синтаксический анализатор, почти равный по возможностям оригинальным регулярным выражениям Perl. Я просто обязан о нём написать.
Сегодня мы попытаемся запрограммировать простой интерпретируемый язык.
Персональные блоги → вышел boost 1.40.0
Как-то незаметно еще в конце августа вышла новая версия библиотеки boost.
Исправлено большое количество багов а также обновлена документация.
www.boost.org/users/download/version_1_40_0
Исправлено большое количество багов а также обновлена документация.
www.boost.org/users/download/version_1_40_0