Here is the simpliest (I think) boost-preprocessor library based approach (from stackoverflow) for converting enum values to string:
#include <boost/preprocessor.hpp>
#define X_ENUM_STRING_TOSTRING_CASE(r, data, elem) \
case elem : return BOOST_PP_STRINGIZE(elem);
#define ENUM_STRING(name, enumerators) \
enum name \
{ \
BOOST_PP_SEQ_ENUM(enumerators) \
}; \
\
inline const char* toString(name val) \
{ \
switch (val) \
{ \
BOOST_PP_SEQ_FOR_EACH( \
X_ENUM_STRING_TOSTRING_CASE, \
name, \
enumerators \
) \
default: \
assert(false); return "[Unknown " BOOST_PP_STRINGIZE(name) "]"; \
} \
}
// Usage sample:
ENUM_STRING(Button, (Ok)(Close)(Retry)(Yes)(No)(Abort)(Help)(Cancel))
void foo()
{
std::string btnHelpName = toString(Button::Help); // btnHelpName == "Help"
std::string btnCloseName = toString(Button::Close); // btnCloseName == "Close"
}
Monday, June 29, 2015
Tuesday, November 25, 2014
How to revert a singly linked list
struct Node{
Node* next;
int value;
};
Node* revert_iteratively(Node* node)
{
Node* new_node = nullptr;
while (node)
{
auto next = node->next;
node->next = new_node;
new_node = node;
node = next;
}
return new_node;
}
Node* revert_iteratively_simple(Node* node)
{
using std::swap;
for (Node* tmp = nullptr; swap(node, tmp), tmp; swap(node, tmp->next));
return node;
}
Node* revert_recursively(Node* node)
{
if (!node || !node->next)
return node;
auto new_node = revert_recursively(node->next);
node->next->next = node;
node->next = nullptr;
return new_node;
}
Sunday, December 29, 2013
Three ways to get UTC time in C++
1. C++ way:
#include <ctime>std::string currentDateTimeUTC( )
{
struct tm tm;
std::time_t time = std::time(nullptr);
if (gmtime_s(&tm, &time))
return ("");
char utc[_countof("1970-01-01T00:00:00")];
strftime(utc, _countof(utc), "%Y-%m-%dT%H:%M:%S", &tm);
return (utc);
}
auto result = currentDateTimeUTC( );
2. boost way:
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace boost::posix_time;
auto result = to_iso_extended_string(second_clock::universal_time());
3. Qt way:
#include <QDateTime>
auto result = QDateTime::currentDateTimeUtc().toString(Qt::ISODate).toStdString();
Friday, August 2, 2013
How to fast initialize a really big array with 16, 32, 64 bit asf values
Sometimes we need a version of memset which sets a value that is larger than one byte. memset only uses one byte of the value passed in and does byte-wise initialization. If you want to initialize an array with a particular value larger than one byte, just use these approaches:
1. Just use a simple for ( ; ; ) In most cases this is a simple and good way.
2. std::fill, std::fill_n
#define BUFF_SIZE 1024 * 1024 * 1536
...
uint16_t val16 = 10000;
uint32_t val32 = 10000 * 10000L;
uint64_t val64 = 10000 * 10000 * 10000LL;
void* buff = new uint8_t[BUFF_SIZE];
...
std::fill_n((uint16_t*)buff, BUFF_SIZE / sizeof(val16), val16);
std::fill_n((uint32_t*)buff, BUFF_SIZE / sizeof(val32), val32);
std::fill_n((uint64_t*)buff, BUFF_SIZE / sizeof(val64), val64);
3. The memset function is very optimized in the compilers. Some implementations offer a 16-bit version memsetw, but that's not everywhere. The memcpy implementations are often written with SIMD instructions which makes it possible to shuffle 128 bits at a time. SIMD instructions are assembly instructions that can perform the same operation on each element in a vector up to 16 bytes long. That includes load and store instructions. So, here is a memsetx function which is implemented via memcpy:
template <typename T>
void memsetx(void* dst, T& val, unsigned int size)
{
uint32_t i = 0;
for ( ; i < (size & (~(sizeof(T) - 1))); i += sizeof(T))
memcpy((uint8_t*)dst + i, &val, sizeof(T));
for ( ; i < size; ++i)
((uint8_t*)dst)[i] = ((uint8_t*)&val)[i & (sizeof(T) - 1)];
}
...
memsetx(buff, val16, BUFF_SIZE);
memsetx(buff, val32, BUFF_SIZE);
memsetx(buff, val64, BUFF_SIZE);
...
memsetx(buff, val1024, BUFF_SIZE);
...
1. Just use a simple for ( ; ; ) In most cases this is a simple and good way.
2. std::fill, std::fill_n
#define BUFF_SIZE 1024 * 1024 * 1536
...
uint16_t val16 = 10000;
uint32_t val32 = 10000 * 10000L;
uint64_t val64 = 10000 * 10000 * 10000LL;
void* buff = new uint8_t[BUFF_SIZE];
...
std::fill_n((uint16_t*)buff, BUFF_SIZE / sizeof(val16), val16);
std::fill_n((uint32_t*)buff, BUFF_SIZE / sizeof(val32), val32);
std::fill_n((uint64_t*)buff, BUFF_SIZE / sizeof(val64), val64);
3. The memset function is very optimized in the compilers. Some implementations offer a 16-bit version memsetw, but that's not everywhere. The memcpy implementations are often written with SIMD instructions which makes it possible to shuffle 128 bits at a time. SIMD instructions are assembly instructions that can perform the same operation on each element in a vector up to 16 bytes long. That includes load and store instructions. So, here is a memsetx function which is implemented via memcpy:
template <typename T>
void memsetx(void* dst, T& val, unsigned int size)
{
uint32_t i = 0;
for ( ; i < (size & (~(sizeof(T) - 1))); i += sizeof(T))
memcpy((uint8_t*)dst + i, &val, sizeof(T));
for ( ; i < size; ++i)
((uint8_t*)dst)[i] = ((uint8_t*)&val)[i & (sizeof(T) - 1)];
}
...
memsetx(buff, val16, BUFF_SIZE);
memsetx(buff, val32, BUFF_SIZE);
memsetx(buff, val64, BUFF_SIZE);
...
memsetx(buff, val1024, BUFF_SIZE);
...
Monday, November 26, 2012
HRESULT lookup tool
There is a useful tool HRPlus for those who works with Microsoft COM. This tool can lookup HRESULTs. You can lookup different codes in binaries, also you can create a new own codes:
Saturday, November 24, 2012
How to: djvu and kindle
There are a lot of ways to perform DJVU to PDF converting. I have investigated a lot of them(online tools, pdf-printers and standalone tools) - and all of them were awful(bad speed, bad quality, shareware, etc.). But recently i've found a nice tool, which performs necessary converting better then others:
1. Go to djvu.sourceforge.net
2. Download binary package(in example my target platform is Windows)
3. Use ddjvu.exe tool, for convertation f.e.:
C:\Program Files (x86)\DjVuZone\DjVuLibre>ddjvu -format=pdf book.djvu book.pdf
1. Go to djvu.sourceforge.net
2. Download binary package(in example my target platform is Windows)
3. Use ddjvu.exe tool, for convertation f.e.:
C:\Program Files (x86)\DjVuZone\DjVuLibre>ddjvu -format=pdf book.djvu book.pdf
Sunday, July 29, 2012
Yoda Conditions

Using
if (constant == variable) instead of if (variable == constant), like if (4 == foo). Because it's like saying "if blue is the sky" or "if tall is the man".
Monday, July 16, 2012
IID_PPV_ARGS
Useful macro, instead this:
hr = CoCreateInstance(
__uuidof(FileOpenDialog), NULL, CLSCTX_ALL,
__uuidof(IFileDialogCustomize), reinterpret_cast<void**>(&pFileOpen));
we can write:
hr = CoCreateInstance(
__uuidof(FileOpenDialog), NULL, CLSCTX_ALL,
IID_PPV_ARGS(&pFileOpen));
hr = CoCreateInstance(
__uuidof(FileOpenDialog), NULL, CLSCTX_ALL,
__uuidof(IFileDialogCustomize), reinterpret_cast<void**>(&pFileOpen));
we can write:
hr = CoCreateInstance(
__uuidof(FileOpenDialog), NULL, CLSCTX_ALL,
IID_PPV_ARGS(&pFileOpen));
Thursday, July 12, 2012
std::vector of pointers vs vector of elements/values
Some info about pointer vs value.
Vector of elements:
+Do not need to free/allocate memory for elements
+Keep it simple
+All elements memory allocated as one memory block - it increases cache hit and reduces memory fragmentation
+STL algorithms friendly
+Do not uses additional memory for pointer
Vector of pointers:
+Polymorphism
+If we don't know how much of memory we will need
+If we will need a lot of large objects
+Small pointers size useful for pointer to elements swaps
Vector of elements:
+Do not need to free/allocate memory for elements
+Keep it simple
+All elements memory allocated as one memory block - it increases cache hit and reduces memory fragmentation
+STL algorithms friendly
+Do not uses additional memory for pointer
Vector of pointers:
+Polymorphism
+If we don't know how much of memory we will need
+If we will need a lot of large objects
+Small pointers size useful for pointer to elements swaps
Tuesday, February 28, 2012
class and struct in C++
Differences between keywords class and struct in C++:
- In absence of an access-specifier for a base class, public is assumed when the derived class is declared struct and private is assumed when the class is declared class;
- Member of a class defined with the keyword class are private by default. Members of a class defined with the keywords struct or union are public by default;
- Keyword class can be used to declare a template parameter, while struct cannot;
- Keyword struct is compatible with C language, while class is not.
- Member of a class defined with the keyword class are private by default. Members of a class defined with the keywords struct or union are public by default;
- Keyword class can be used to declare a template parameter, while struct cannot;
- Keyword struct is compatible with C language, while class is not.
Thursday, November 17, 2011
using namespace
Есть хорошая книга котрую я давно читал – «Стандарты программирования на C++ 101 правило и рекомендация» Герб Саттер, Андрей Александреску. Там была вот такая рекомендация №59: «Не используйте using для пространств имен в заголовочных файлах или перед директивой #include». И вот я заметил, что в коде сгенеренным мастером ATL используется using namespace в *.h:
...
using namespace ATL;
// CNoNamePreview
class ATL_NO_VTABLE CNoNamePreview :
public CComObjectRootEx< CComSingleThreadModel >,
public CComCoClass< CNoNamePreview, &CLSID_NoNamePreview >,
public IObjectWithSiteImpl< CNoNamePreview >,
...
Вроде ничего такого, т.к. этот хедер дальше нигде не должен включатся. Но как-то непривычно что-ли. То что выше относится к MSVS2010sp1, а вот так делал мастер в MSVS2008sp1:
// stdafx.h
...
#define _ATL_NO_AUTOMATIC_NAMESPACE
...
using namespace ATL;
...
Wednesday, November 16, 2011
Custom Deleter - shared_ptr<> vs unique_ptr<>
Раньше можно было делать так:
// shared_ptr< > way
LPWSTR lpName = NULL;
std::tr1::shared_ptr< WCHAR > spName( (
spItem->GetDisplayName( SIGDN_FILESYSPATH, &lpName ), lpName ),
CoTaskMemFree );
Теперь можно и вот так:
// unique_ptr< > way
typedef void ( __cdecl* _COM_DELETER )( LPVOID );
LPWSTR lpName = NULL;
std::unique_ptr< WCHAR, _COM_DELETER > spName( (
spItem->GetDisplayName( SIGDN_FILESYSPATH, &lpName ), lpName ),
CoTaskMemFree );
В случае с unique_ptr< > нет дополнительного оверхеда на счетчик и проверки-вызова делитера в рантайме, но теперь приходится указывать тип. А ещё можно делать такое:
std::unique_ptr< int[ ] > ar( new int[ 100 ] );
Thursday, May 5, 2011
Virtual inheritance in C++
Часто встречал вопрос на эту тему. Ответ что это и как работает, как бы намекает, что человек как минимум внимательно читает книги (т.к. большинство людей этот вид наследования не используют). Обычно ответ такой: нужно чтоб избежать двух копий базового класса при «ромбовидном» наследовании.
Обычно на этом всё заканчивается – мол, молодец (читаешь внимательно).
Но вопросы нужно продолжить. Например:
– Что если не использовать виртуальное наследование в данном случае? Как тогда?
О:…
– Во всех ли случаях этот вид наследования нужен, если нет, то в каких?
О: Если нет дублирования данных, только функции – то в принципе это дублирование никому не мешает.
– В MS COM есть базовый класс IUnknown, и есть дальше почти всегда «ромбовидное» наследование, но виртуальность тут не используется, почему?
О: Бинарный стандарт COM требует такую структуру в памяти, где у каждого есть своя копия таблицы IUnknown.
– Как выглядит это в памяти, и что со скоростью?
Далее после этих вопросов, можно спросить, а зачем вообще нужно наследование? Что делать если его нет? Хорошо или плохо его использовать, почему, когда, где? Очень болезненная тема для многих. Часто в проекте получается, типа один говорит «Не трогайте мои классы/мою архитектуру!», а ему в ответ «OOP must Go!». Вот в тему очень полезная статья/блог: avoiding inheritance dependency
Friday, April 1, 2011
bits count
Как-то давненько хотел написать пост на эту тему, и вот сегодня увидел мега-баннер от Global Logic:
Собственно теперь повод есть( сори за баян если что ).
ИМХО задача бесполезная, но при этом популярная в собеседованиях С/С++. Решается она не сложно - через деление на 2( я решил не рассматривать этот случай ), либо сдвигом, либо масками. Сдвиг – очевидно более простое решение, и его обычно подразумевают. Вот пример реализации сдвигом:
// Решение сдвигом
int runtime_bits_count( unsigned int n )
{
unsigned int c = 0;
for ( ; n; n >>= 1 ) n & 1 && ++c;
return c;
}
Также нужно заметить, что математики уже давно всё посчитали, и для каждого типа целого есть некий набор хитрых манипуляций и масок. Вот пример для 32-битного целого:
// Более быстрый алгоритм с масками
// Генри Уоррен мл. Алгоритмические трюки для програмистов.
// Глава 5 Подсчет битов, листинг 5.1
unsigned int runtime_fast_bits_count( unsigned int n )
{
n = n - ( ( n >> 1 ) & 0x55555555 );
n = ( n & 0x33333333 ) + ( ( n >> 2 ) & 0x33333333 );
n = ( n + ( n >> 4 ) ) & 0x0F0F0F0F;
n = n + ( n >> 8 );
n = n + ( n >> 16 );
return n & 0x0000003F;
}
Я не зря написал в названии функций ‘runtime’, ведь функция считает установленные биты только во время выполнения. Но если входящий параметр константа/дефайн/число – то можно было б посчитать всё во время компиляции. Вот пример решения для однобайтного целого на Си:
// Compile-time bits_count в стиле С
#define bits_count( n ) \
( n & 0x01 ? 1 : 0 ) + ( n & 0x02 ? 1 : 0 ) + \
( n & 0x04 ? 1 : 0 ) + ( n & 0x08 ? 1 : 0 ) + \
( n & 0x10 ? 1 : 0 ) + ( n & 0x20 ? 1 : 0 ) + \
( n & 0x40 ? 1 : 0 ) + ( n & 0x80 ? 1 : 0 )
const unsigned char b = 120;
int res = bits_count( b ); // compile-time
Для однобайтного на С++:
// Тот же подход но в стиле С++
template < unsigned char n >
struct bits_count
{
enum
{
RES = ( n & 0x01 ? 1 : 0 ) + ( n & 0x02 ? 1 : 0 ) +
( n & 0x04 ? 1 : 0 ) + ( n & 0x08 ? 1 : 0 ) +
( n & 0x10 ? 1 : 0 ) + ( n & 0x20 ? 1 : 0 ) +
( n & 0x40 ? 1 : 0 ) + ( n & 0x80 ? 1 : 0 )
};
};
const unsigned char b = 120;
int res = bits_count < b >::RES; // compile-time
Круто. А теперь еще немножко и получим менее зависимую от ширины типа реализацию:
template < unsigned int x >
struct bitscount
{
static const unsigned int n = bitscount < x / 2 >::n + x % 2;
};
template < >
struct bitscount < 0 >
{
static const unsigned int n = 0;
};
#define dec2bin( x ) bitscount < ( x ) >::n
int _tmain( int argc, _TCHAR* argv[] )
{
const int b = 60000; // 32 bit!
size_t t = dec2bin( b ); // in compile-time
return 0;
}
Теперь остаеться написать реализацию для n-байтного целого, где если это константа – вычисление должно быть во время компиляции. Иногда говорят: «надо заставить компилятор за нас думать», оно вроде сейчас так и получается, но думаю всё равно я, а он компилит). Думал, думал – и не придумал). Зато нашел полезную вещь которая детектит константность во время компиляции:
struct check_const
{
struct Temp { Temp( int x ) { } };
static char chk2( void* ) { return 0; }
static int chk2( Temp ) { return 0; }
};
#define is_const( t ) \
( sizeof( check_const::chk2( 0 + !!( t ) ) ) != sizeof( check_const::chk2( 0 + !( t ) ) ) )
Subscribe to:
Posts (Atom)

