cpp_util_2 Оглавление
Создано системой Doxygen 1.3.5
Fri Feb 20 09:37:36 2004

Оглавление

1 cpp_util_2 Титульная страница
2 cpp_util_2 Алфавитный указатель пространства имен
 2.1 cpp_util_2 Пространства имен
3 cpp_util_2 Иерархический список классов
 3.1 cpp_util_2 Иерархия классов
4 cpp_util_2 Алфавитный указатель классов
 4.1 cpp_util_2 Классы
5 cpp_util_2 Список файлов
 5.1 cpp_util_2 Файлы
6 cpp_util_2 Алфавитный указатель тематических описаний
 6.1 cpp_util_2 Описания
7 cpp_util_2 Пространства имен
 7.1 Пространство имен cpp_util_2
  7.1.1 Подробное описание
  7.1.2 Функции
 7.2 Пространство имен cpp_util_2::impl
  7.2.1 Подробное описание
 7.3 Пространство имен cpp_util_2::lexcasts
  7.3.1 Подробное описание
  7.3.2 Функции
 7.4 Пространство имен cpp_util_2::lexcasts::impl
  7.4.1 Подробное описание
8 cpp_util_2 Классы
 8.1 Шаблон структуры cpp_util_2::lexcasts::all_cont_t< Cont >
  8.1.1 Подробное описание
 8.2 Шаблон структуры cpp_util_2::lexcasts::all_t< It >
  8.2.1 Подробное описание
 8.3 Шаблон структуры cpp_util_2::lexcasts::all_using_t< It, Putter >
  8.3.1 Подробное описание
 8.4 Шаблон класса cpp_util_2::const_unary_method_t< R, T, A >
  8.4.1 Подробное описание
  8.4.2 Конструктор(ы)
 8.5 Структура cpp_util_2::lexcasts::def_putter
  8.5.1 Подробное описание
 8.6 Структура cpp_util_2::lexcasts::hex
  8.6.1 Подробное описание
 8.7 Класс cpp_util_2::lexcasts::hex_0x
  8.7.1 Подробное описание
 8.8 Класс cpp_util_2::lexcasts::hex_bslashx
  8.8.1 Подробное описание
 8.9 Структура cpp_util_2::lexcasts::hex_getter
  8.9.1 Подробное описание
 8.10 Класс cpp_util_2::nocopy_t
  8.10.1 Подробное описание
 8.11 Класс cpp_util_2::lexcasts::prefixed_hex
  8.11.1 Подробное описание
 8.12 Шаблон класса cpp_util_2::impl::return_type_detector_t< R >
  8.12.1 Подробное описание
  8.12.2 Определения типов
 8.13 Шаблон класса cpp_util_2::impl::return_type_detector_t< void >
  8.13.1 Подробное описание
  8.13.2 Определения типов
 8.14 Шаблон класса cpp_util_2::unary_method_t< R, T, A >
  8.14.1 Подробное описание
  8.14.2 Конструктор(ы)
9 cpp_util_2 Файлы
 9.1 Файл cpp_util_2/h/cpp_util.hpp
  9.1.1 Подробное описание
 9.2 Файл cpp_util_2/h/defs.hpp
  9.2.1 Подробное описание
  9.2.2 Макросы
 9.3 Файл cpp_util_2/h/detect_compiler.hpp
  9.3.1 Подробное описание
  9.3.2 Макросы
 9.4 Файл cpp_util_2/h/lexcast.hpp
  9.4.1 Подробное описание
 9.5 Файл cpp_util_2/h/nocopy.hpp
  9.5.1 Подробное описание
 9.6 Файл cpp_util_2/h/unary_method.hpp
  9.6.1 Подробное описание
 9.7 Файл cpp_util_2/lexcasts/h/util.hpp
  9.7.1 Подробное описание
10 cpp_util_2 Примеры
 10.1 lexcast/throw/main.cpp
 10.2 lexcast/util/main.cpp
 10.3 unary_method/find_if/main.cpp
 10.4 unary_method/for_each_find_min_max/main.cpp
 10.5 unary_method/for_each_modify/main.cpp
11 cpp_util_2 Тематические описания
 11.1 cpp_util_2: Обертки для вызова унарных методов объектов
  11.1.1 Введение
  11.1.2 Недостаток
 11.2 cpp_util_2: Средства lexcasts
  11.2.1 Введение
  11.2.2 Назначение
  11.2.3 Принцип работы
  11.2.4 Преобразование сложных типов
 11.3 cpp_util_2: Список модификаций.
  11.3.1 2.1.0
  11.3.2 2.0.3
  11.3.3 2.0.2
  11.3.4 2.0.1
 11.4 Список устаревших определений и описаний

Глава 1
cpp_util_2 Титульная страница

/*  
 
Yauheni A. Akhotnikau (C) 1997-2004  
e-mail: eao197@yahoo.com  
 
Permission is granted to anyone to use this software for any purpose on any  
computer system, and to redistribute it freely, subject to the following  
restrictions:  
 
1. This software is distributed in the hope that it will be useful,  
   but WITHOUT ANY WARRANTY; without even the implied warranty of  
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
 
2. The origin of this software must not be misrepresented, either by  
   explicit claim or by omission.  
 
3. Altered versions must be plainly marked as such, and must not be  
   misrepresented as being the original software.  
 
*/

cpp_util_2: Список модификаций.

cpp_util_2: Обертки для вызова унарных методов объектов

cpp_util_2: Средства lexcasts

Глава 2
cpp_util_2 Алфавитный указатель пространства имен

2.1 cpp_util_2 Пространства имен

Полный список документированных пространств имен.

cpp_util_2 (Основное пространство имен проекта cpp_util_2 )
cpp_util_2::impl (Детали реализации проекта cpp_util_2 )
cpp_util_2::lexcasts (Дополнительные вспомогательные средства для использования вместе с функцией cpp_util_2::lexcast() )
cpp_util_2::lexcasts::impl (Детали реализации )

Глава 3
cpp_util_2 Иерархический список классов

3.1 cpp_util_2 Иерархия классов

Иерархия классов.

cpp_util_2::lexcasts::all_cont_t< Cont >
cpp_util_2::lexcasts::all_t< It >
cpp_util_2::lexcasts::all_using_t< It, Putter >
cpp_util_2::const_unary_method_t< R, T, A >
cpp_util_2::lexcasts::def_putter
cpp_util_2::lexcasts::hex
cpp_util_2::lexcasts::hex_getter
cpp_util_2::nocopy_t
cpp_util_2::lexcasts::prefixed_hex
cpp_util_2::lexcasts::hex_0x
cpp_util_2::lexcasts::hex_bslashx
cpp_util_2::impl::return_type_detector_t< R >
cpp_util_2::impl::return_type_detector_t< void >
cpp_util_2::unary_method_t< R, T, A >

Глава 4
cpp_util_2 Алфавитный указатель классов

4.1 cpp_util_2 Классы

Классы с их кратким описанием.

cpp_util_2::lexcasts::all_cont_t< Cont > (Вспомогательная структура для преобразования значений на которые указывают итераторы )
cpp_util_2::lexcasts::all_t< It > (Вспомогательная структура для преобразования значений на которые указывают итераторы )
cpp_util_2::lexcasts::all_using_t< It, Putter > (Вспомогательная структура для преобразования значений на которые указывают итераторы )
cpp_util_2::const_unary_method_t< R, T, A > (Класс-обертка для вызова константного унарного метода объекта )
cpp_util_2::lexcasts::def_putter (Преобразователь значения, который использует стандартный оператор сдвига, определенный для данного типа )
cpp_util_2::lexcasts::hex (Преобразование целочисленного значения в шестнадцатиричное представление )
cpp_util_2::lexcasts::hex_0x (Преобразование целочисленного значения в шестнадцатиричное представление с добавлением стандартного для C/C++ префикса 0x )
cpp_util_2::lexcasts::hex_bslashx (Преобразование целочисленного значения в шестнадцатиричное представление с добавлением стандартного для C/C++ префикса \x )
cpp_util_2::lexcasts::hex_getter (Преобразование шестнадцатиричное представления числа в число )
cpp_util_2::nocopy_t (Базовый класс, запрещающий копирование объектов )
cpp_util_2::lexcasts::prefixed_hex (Преобразование целочисленного значения в шестнадцатиричное представление с добавлением указанного префикса )
cpp_util_2::impl::return_type_detector_t< R > (Обертка для определения типа возвращаемого значения )
cpp_util_2::impl::return_type_detector_t< void > (Спецализация шаблона return_type_detector_t для методов, возвращающих void )
cpp_util_2::unary_method_t< R, T, A > (Класс-обертка для вызова унарного неконстантного метода объекта )

Глава 5
cpp_util_2 Список файлов

5.1 cpp_util_2 Файлы

Полный список документированных файлов.

cpp_util_2/h/cpp_util.hpp (Общий файл для всех макросов )
cpp_util_2/h/defs.hpp (Не привязанные к компилятору макросы )
cpp_util_2/h/detect_compiler.hpp (Зависящие от компилятора макросы )
cpp_util_2/h/lexcast.hpp (Функция для конвертации значений из одного типа в другой с использованием промежуточного текстового представления )
cpp_util_2/h/nocopy.hpp (Класс cpp_util_2::nocopy_t )
cpp_util_2/h/unary_method.hpp (Класс-обертка для вызова унарного метода объекта )
cpp_util_2/lexcasts/h/util.hpp (Вспомогательные объекты для преобразования и извлечения значений )

Глава 6
cpp_util_2 Алфавитный указатель тематических описаний

6.1 cpp_util_2 Описания

Полный список дополнительных описаний.

cpp_util_2: Обертки для вызова унарных методов объектов
cpp_util_2: Средства lexcasts
cpp_util_2: Список модификаций.
Список устаревших определений и описаний

Глава 7
cpp_util_2 Пространства имен

7.1 Пространство имен cpp_util_2

7.1.1 Подробное описание

Основное пространство имен проекта cpp_util_2.

Классы

Функции

7.1.2 Функции

7.1.2.1 template<class To, class From, class Putter, class Getter> To lexcast (const From & f, const Putter & putter, const Getter & getter)

Функция для конвертации значений из одного типа в другой с использованием промежуточного текстового представления и специальноых способов преобразования значения.

Начиная с:
v.2.1.0

Данный вариант lexcast использует объект-преобразователь, который осуществляет преобразование значения в std::ostream и объект-преобразователь, который считывает значение из std::istream.

Если требуется только специальный объект-getter, то в качестве объекта-putter можно указать объект cpp_util_2::lexcasts::def_putter:
// Извлекаем число из строкового шестнадцатиричного представления.  
int i = cpp_util_2::lexcast< int >( "ffab",  
  cpp_util_2::lexcasts::def_putter(),  
  cpp_util_2::lexcasts::hex_getter() );

Требования к типу Putter
Тип Putter должен иметь метод operator() следующего формата:
void  
operator( std::ostream & to, const From & what ) const;

Требования к типу Getter
Тип Getter должен иметь метод operator() следующего формата:
void  
operator( std::istream & to, To & what ) const;

Аргументы:
f
Что преобразуется.
putter
Как преобразуется в std::ostream.
getter
Как преобразуется из std::istream.

7.1.2.2 template<class To, class From, class Putter> To lexcast (const From & f, const Putter & putter)

Функция для конвертации значений из одного типа в другой с использованием промежуточного текстового представления и специального способа преобразования значения.

Начиная с:
v.2.1.0

Данный вариант lexcast использует объект-преобразователь, который осуществляет преобразование значения в std::stringstream.

Требования к типу Putter
Тип Putter должен иметь метод operator() следующего формата:
void  
operator( std::ostream & to, const From & what ) const;

Аргументы:
f
Что преобразуется.
putter
Как преобразуется.

7.1.2.3 template<class To, class From> To lexcast (const From & f)

Функция для конвертации значений из одного типа в другой с использованием промежуточного текстового представления.

Начиная с:
v.2.0.2

В ряде случаев возникает задача преобразования некоторого значения в его текстовое представление. Например, при порождении исключений:
// Способ 1. Использование sprintf.  
const std::string &  
my_string_vector_t::operator[]( unsigned int index ) const  
{  
  if( index >= size() )  
  {  
    // Преобразуем index в строку, чтобы можно  
    // было сформировать подробное описание ошибки.  
    char tmp[ 32 ];  
    sprintf( tmp, "%u", index );  
    throw std::out_of_range(  
      std::string( "index is too big" ) + tmp );  
  }  
  ...  
}  
// Способ 2. Использование std::ostringstream.  
const std::string &  
my_string_vector_t::operator[]( unsigned int index ) const  
{  
  if( index >= size() )  
  {  
    // Преобразуем index в строку, чтобы можно  
    // было сформировать подробное описание ошибки.  
    std::ostringstream tmp;  
    tmp << index;  
    throw std::out_of_range(  
      std::string( "index is too big" ) + tmp.str() );  
  }  
  ...  
}

Оба этих способа усложняют код не нужными подробностями преобразования одного значения в строковое представление. И, хотя способ с sprintf более эффективен, он более сложен в сопровождении, т.к. формат sprintf жестко связан с типом параметра index. Если со временем index поменяет тип (на unsigned long для очень больших массивов или на std::string для ассоциативных массивов), то придется помнить про особенность форматной строки sprintf. В случае с std::ostringstream такой проблемы нет.

Функция lexcast() упрощает подобные преобразования, сохраняя все достоинства и недостатки способа с применением std::ostringstream. В приведенном примере функция lexcast() может быть использована следующим образом:
// Способ 3. Использование cpp_util_2::lexcast.  
const std::string &  
my_string_vector_t::operator[]( unsigned int index ) const  
{  
  if( index >= size() )  
    throw std::out_of_range(  
      std::string( "index is too big" ) +  
      cpp_util_2::lexcast< std::string >( index ) );  
  ...  
}

или, что еще проще:
// Способ 4. Использование cpp_util_2::slexcast.  
const std::string &  
my_string_vector_t::operator[]( unsigned int index ) const  
{  
  if( index >= size() )  
    throw std::out_of_range(  
      std::string( "index is too big" ) +  
      cpp_util_2::slexcast( index ) );  
  ...  
}

То, что для преобразования значений используется промежуточное текстовое представление позволяет не только преобразовывать числовые значения в строку, но и преобразовывать строку в числовое значение.

Порождение исключений.
Сама функция lexcast() исключений не порождает и не контролирует успешность выполнения преобразований. Но lexcast не перехватывает никаких исключений, которые могут быть порождены операторами сдвига.

Требование к типу From.
Для типа From должен быть определен оператор сдвига в std::ostream.

Требование к типу To.
Для типа \с To должен быть определен оператор сдвига из std::istream.

Возвращает:
Значение, полученное преобразованием f в текстовое представление, а затем считанное из текстового представления. Результат не определен, если текстовое представление f не может быть корректно приведено к типу To.

См. также:
cpp_util_2::slexcast()

Аргументы:
f
Что преобразуется.

7.1.2.4 template<class From, class Putter> std::string slexcast (const From & f, const Putter & putter)

Начиная с:
v.2.1.0

Вариант функции slexcast() с использованием объекта-преобразователя значения в строку.

Требования к типу Putter
Тип Putter должен иметь метод operator() следующего формата:
void  
operator( std::ostream & to, const From & what ) const;

Аргументы:
f
Что преобразуется.
putter
Как преобразуется.

7.1.2.5 template<class From> std::string slexcast (const From & f)

Начиная с:
v.2.1.0

Вариант функции lexcast() для преобразования в строку.

С помощью cpp_util_2::lexcast() можно попытаться преобразовать любой объект в строку, если у этого объекта определен оператор сдвига в std::ostream. Например:
class A  
{  
  int m_a;  
  float m_b;  
  public :  
    std::ostream &  
    dump_to( std::ostream & to ) const  
    {  
      return ( to << "m_a: " << a << ", m_b: " << m_b );  
    }  
};  
inline std::ostream &  
operator<<( std::ostream & to, const A & a )  
{  
  return a.dump_to( to );  
}  
 
void f()  
{  
  A a;  
  std::string str_a( cpp_util_2::lexcast< std::string >( a ) );  
}

Но проблема в том, что в str_a будет содержаться только "m_a:", т.к. оператор >> для std::string извлекает значения из промежуточного std::stringstream в cpp_util_2::lexcast() только до первого пробела.

Функция slexcast() решает эту проблему и позволяет поместить в str_a все содержимое промежуточного std::stringstream. В приведенном примере функцию slexcast() можно использовать так:
void f()  
{  
  A a;  
  std::string str_a( cpp_util_2::slexcast( a ) );  
}

Аргументы:
f
Что преобразуется.

Примеры:

lexcast/util/main.cpp.

7.1.2.6 template<class R, class T, class A> const_unary_method_t< R, T, A > cpp_util_2::unary_method (T * p, R(T::* pfn)(A))

Упрощенный способ создания объекта const_unary_method_t.

Если есть класс:
class actor_t  
{  
  public :  
    void  
    f( const std::string & a );  
};

То создать объект unary_method_t для вызова метода f у объекта типа actor_t можно двумя способами:

Примеры:

unary_method/find_if/main.cpp, unary_method/for_each_find_min_max/main.cpp и unary_method/for_each_modify/main.cpp.

7.2 Пространство имен cpp_util_2::impl

7.2.1 Подробное описание

Детали реализации проекта cpp_util_2.

Классы

Вспомогательные функции, которые осуществляют вызов метода.

7.3 Пространство имен cpp_util_2::lexcasts

7.3.1 Подробное описание

Дополнительные вспомогательные средства для использования вместе с функцией cpp_util_2::lexcast().

Начиная с:
v.2.0.3

Классы

Функции

7.3.2 Функции

7.3.2.1 template<class Cont, class Putter> all_using_t< typename Cont::const_iterator, Putter > all (const Cont & c, const std::string & sep, Putter putter)

Выполнение преобразования всех значений указанного контейнера с использованием указанного преобразователя.

Начиная с:
v.2.0.3

С помощью этой функции можно осуществлять преобразование, например, всех значений контейнера, который обладает методами begin(), end(), возвращающими итераторы:
// Печать шестнадцатиричного представления каждого символа строки.  
std::string hello( "Hello!" );  
std::cout << cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( hello, "",  
    cpp_util_2::lexcasts::hex_bslashx() ) );

Заметки:
После последнего элемента разделитель не печатается.

7.3.2.2 template<class It, class Putter> all_using_t< It, Putter > all (It b, It e, const std::string & sep, Putter putter)

Выполнение преобразования всех значений между указанными итераторами с использованием указанного преобразователя.

Начиная с:
v.2.0.3

С помощью этой функции можно осуществлять преобразование, например, всех значений контейнера или массива (вспомогательный string_getter используется для того, чтобы прочитать из промежуточного буфера все значения вместе с пробелами):
// Печать всех значений из массива.  
unsigned int ui[ 64 ] = { ... };  
std::cout << cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( ui, ui + ( sizeof(ui) / sizeof(ui[0]) ),  
    " ", cpp_util_2::lexcasts::hex_0x() ) );

Заметки:
После последнего элемента разделитель не печатается.

7.3.2.3 template<class Cont> all_cont_t< Cont > all (const Cont & c, const std::string & sep = " ")

Выполнение преобразования всех значений указанного контейнера.

Начиная с:
v.2.0.3

С помощью этой функции можно осуществлять преобразование, например, всех значений контейнера, который обладает методами begin(), end(), возвращающими итераторы (вспомогательный string_getter используется для того, чтобы прочитать из промежуточного буфера все значения вместе с пробелами):
// Печать всех значений вектора строк, разделяя каждое значение  
// переводом строки.  
std::set< std::string > ss;  
...  
std::cout << cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( ss, "\n" ) );

Внимание:
В типе Cont должен быть определен тип const_iterator.

Заметки:
После последнего элемента разделитель не печатается.

7.3.2.4 template<class It> all_t< It > all (It b, It e, const std::string & sep = " ")

Выполнение преобразования всех значений между указанными итераторами.

Начиная с:
v.2.0.3

С помощью этой функции можно осуществлять преобразование, например, всех значений контейнера или массива (вспомогательный string_getter используется для того, чтобы прочитать из промежуточного буфера все значения вместе с пробелами):
// Печать всех значений из массива.  
unsigned int ui[ 64 ] = { ... };  
std::cout << cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( ui, ui + ( sizeof(ui) / sizeof(ui[0]) ) ) );  
 
// Печать всех значений вектора строк, разделяя каждое значение  
// переводом строки.  
std::set< std::string > ss;  
...  
std::cout << cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( ss.begin(), ss.end(), "\n" ) );

Заметки:
После последнего элемента разделитель не печатается.

7.3.2.5 template<class It, class Putter> std::ostream& operator<< (std::ostream & to, const all_using_t< It, Putter > & what)

Преобразование значений.

Заметки:
После последнего элемента разделитель не печатается.

7.3.2.6 template<class Cont> std::ostream& operator<< (std::ostream & to, const all_cont_t< Cont > & what)

Преобразование значений.

Заметки:
После последнего элемента разделитель не печатается.

7.3.2.7 template<class It> std::ostream& operator<< (std::ostream & to, const all_t< It > & what)

Преобразование значений.

Заметки:
После последнего элемента разделитель не печатается.

7.4 Пространство имен cpp_util_2::lexcasts::impl

7.4.1 Подробное описание

Детали реализации.

Специальные случаи ostream_lshift для типа char.

Специальные случаи istream_rshift для типа char.

Функции

Глава 8
cpp_util_2 Классы

8.1 Шаблон структуры cpp_util_2::lexcasts::all_cont_t< Cont >

#include <util.hpp>

8.1.1 Подробное описание

template<class Cont> struct cpp_util_2::lexcasts::all_cont_t< Cont >

Вспомогательная структура для преобразования значений на которые указывают итераторы.

Начиная с:
v.2.0.3

См. также:
cpp_util_2::lexcasts::all().

Открытые члены

Открытые атрибуты

Объявления и описания членов структуры находятся в файле:

8.2 Шаблон структуры cpp_util_2::lexcasts::all_t< It >

#include <util.hpp>

8.2.1 Подробное описание

template<class It> struct cpp_util_2::lexcasts::all_t< It >

Вспомогательная структура для преобразования значений на которые указывают итераторы.

Начиная с:
v.2.0.3

См. также:
cpp_util_2::lexcasts::all().

Открытые члены

Открытые атрибуты

Объявления и описания членов структуры находятся в файле:

8.3 Шаблон структуры cpp_util_2::lexcasts::all_using_t< It, Putter >

#include <util.hpp>

8.3.1 Подробное описание

template<class It, class Putter> struct cpp_util_2::lexcasts::all_using_t< It, Putter >

Вспомогательная структура для преобразования значений на которые указывают итераторы.

Начиная с:
v.2.0.3

См. также:
cpp_util_2::lexcasts::all().

Открытые члены

Открытые атрибуты

Объявления и описания членов структуры находятся в файле:

8.4 Шаблон класса cpp_util_2::const_unary_method_t< R, T, A >

#include <unary_method.hpp>

8.4.1 Подробное описание

template<class R, class T, class A> class cpp_util_2::const_unary_method_t< R, T, A >

Класс-обертка для вызова константного унарного метода объекта.

Подробнее см. cpp_util_2: Обертки для вызова унарных методов объектов.

Открытые типы

Открытые члены

Закрытые данные

8.4.2 Конструктор(ы)

8.4.2.1 template<class R, class T, class A> cpp_util_2::const_unary_method_t< R, T, A >::const_unary_method_t (T * p, R(T::* pfn)(A) const) [inline]

Инициализирующий конструктор.

Аргументы:
p
Объект, у которого нужно вызвать метод.
pfn
Указатель на вызываемый метод.

Объявления и описания членов класса находятся в файле:

8.5 Структура cpp_util_2::lexcasts::def_putter

#include <util.hpp>

8.5.1 Подробное описание

Преобразователь значения, который использует стандартный оператор сдвига, определенный для данного типа.

Примеры:

lexcast/util/main.cpp.

Открытые члены

Объявления и описания членов структуры находятся в файле:

8.6 Структура cpp_util_2::lexcasts::hex

#include <util.hpp>

8.6.1 Подробное описание

Преобразование целочисленного значения в шестнадцатиричное представление.

Начиная с:
v.2.0.3

Для того, чтобы получить в строке шестнадцатиричное представление числа можно воспользоваться классом hex_t в качестве объекта-значения для cpp_util_2::lexcast():
unsigned int ui = 2378;  
std::string str_hex_ui(  
  cpp_util_2::slexcast( ui, cpp_util_2::lexcasts::hex() ) );

Примеры:

lexcast/util/main.cpp.

Открытые члены

Объявления и описания членов структуры находятся в файле:

8.7 Класс cpp_util_2::lexcasts::hex_0x

#include <util.hpp>

Граф наследования:cpp_util_2::lexcasts::hex_0x::


PIC


8.7.1 Подробное описание

Преобразование целочисленного значения в шестнадцатиричное представление с добавлением стандартного для C/C++ префикса 0x.

Начиная с:
v.2.1.0

Для того, чтобы получить в строке шестнадцатиричное представление числа, которое начинается со стандартного C/C++ префикса 0x, можно воспользоваться классом hex_0x в качестве объекта-значения для cpp_util_2::lexcast():
unsigned int ui = 2378;  
std::string str_hex_ui( cpp_util_2::slexcast( ui,  
  cpp_util_2::lexcasts::hex_0x() ) );

Примеры:

lexcast/util/main.cpp.

Объявления и описания членов класса находятся в файле:

8.8 Класс cpp_util_2::lexcasts::hex_bslashx

#include <util.hpp>

Граф наследования:cpp_util_2::lexcasts::hex_bslashx::


PIC


8.8.1 Подробное описание

Преобразование целочисленного значения в шестнадцатиричное представление с добавлением стандартного для C/C++ префикса \x.

Начиная с:
v.2.1.0

Для того, чтобы получить в строке шестнадцатиричное представление числа, которое начинается со стандартного C/C++ префикса \x, можно воспользоваться классом hex_bslashx_t в качестве объекта-значения для cpp_util_2::lexcast():
unsigned int ui = 2378;  
std::string str_hex_ui( cpp_util_2::slexcast( ui,  
  cpp_util_2::lexcasts::hex_bslashx() ) );

Примеры:

lexcast/util/main.cpp.

Объявления и описания членов класса находятся в файле:

8.9 Структура cpp_util_2::lexcasts::hex_getter

#include <util.hpp>

8.9.1 Подробное описание

Преобразование шестнадцатиричное представления числа в число.

Начиная с:
v.2.0.3

Для того, чтобы извлечь из строкого шестнадцатиричное представление числа значение можно воспользоваться классом hex_getter в качестве объекта-извлекателя для cpp_util_2::lexcast():
unsigned int ui = cpp_util_2::lexcast< unsigned int >(  
  std::string( "ff5d" ),  
  cpp_util_2::lexcasts::def_putter(),  
  cpp_util_2::lexcasts::hex_getter() );

Примеры:

lexcast/util/main.cpp.

Открытые члены

Объявления и описания членов структуры находятся в файле:

8.10 Класс cpp_util_2::nocopy_t

#include <nocopy.hpp>

8.10.1 Подробное описание

Базовый класс, запрещающий копирование объектов.

Класс, который специально имеет закрытые конструктор и оператор копирования. Благодоря этому производные от nocopy_t классы так же имеют закрытые конструктор и оператор копирования.

Пример использования:
  class my_smart_ptr_t : private cpp_util_2::nocopy_t  
  {  
    private :  
      // Из-за этого указателя объекты my_smart_ptr_t  
      // не могут копироваться.  
      void *  m_ptr;  
    public :  
      my_smart_ptr_t();  
      ~my_smart_ptr_t();  
      ...  
  };

Благодоря закрытому наследованию нельзя преобразовать my_smart_ptr_t * к cpp_util_2::nocopy_t.

Закрытые члены

Объявления и описания членов класса находятся в файле:

8.11 Класс cpp_util_2::lexcasts::prefixed_hex

#include <util.hpp>

Граф наследования:cpp_util_2::lexcasts::prefixed_hex::


PIC


8.11.1 Подробное описание

Преобразование целочисленного значения в шестнадцатиричное представление с добавлением указанного префикса.

Открытые члены

Закрытые данные

Объявления и описания членов класса находятся в файле:

8.12 Шаблон класса cpp_util_2::impl::return_type_detector_t< R >

#include <unary_method.hpp>

8.12.1 Подробное описание

template<class R> class cpp_util_2::impl::return_type_detector_t< R >

Обертка для определения типа возвращаемого значения.

Необходимость в этой обертке возникла из-за того, что VC6.0 не позволяет возвращать тип void:
void  
f() {}  
 
void  
call_f()  
{  
  return f();  
}

Поэтому для методов, возвращающих void нужно создавать обертки вызова, которые возврают какой-либо тип, например, int:
void  
f() {}  
 
int  
call_f()  
{  
  f();  
  return 0;  
}

Шаблон return_type_detector_t берет на себя задачу определения типа возвращаемого значения. Для методов, возвращающих void создается специализация return_type_detector_t< void >, которая возвращает тип int.

Открытые типы

8.12.2 Определения типов

8.12.2.1 template<class R> typedef char cpp_util_2::impl::return_type_detector_t< R >::dummy_arg_type_t

Тип дополнительного аргумента в для функции call_method.

Функции call_method(), получающие последним аргументом char * предназначены для вызова методов, которые реально что-то возвращают.

Объявления и описания членов класса находятся в файле:

8.13 Шаблон класса cpp_util_2::impl::return_type_detector_t< void >

#include <unary_method.hpp>

8.13.1 Подробное описание

template<> class cpp_util_2::impl::return_type_detector_t< void >

Спецализация шаблона return_type_detector_t для методов, возвращающих void.

Открытые типы

8.13.2 Определения типов

8.13.2.1 typedef int cpp_util_2::impl::return_type_detector_t< void >::dummy_arg_type_t

Тип дополнительного аргумента в для функции call_method.

Функции call_method(), получающие последним аргументом int * предназначены для вызова методов, которые ничего возвращают.

Объявления и описания членов класса находятся в файле:

8.14 Шаблон класса cpp_util_2::unary_method_t< R, T, A >

#include <unary_method.hpp>

8.14.1 Подробное описание

template<class R, class T, class A> class cpp_util_2::unary_method_t< R, T, A >

Класс-обертка для вызова унарного неконстантного метода объекта.

Подробнее см. cpp_util_2: Обертки для вызова унарных методов объектов.

Открытые типы

Открытые члены

Закрытые данные

8.14.2 Конструктор(ы)

8.14.2.1 template<class R, class T, class A> cpp_util_2::unary_method_t< R, T, A >::unary_method_t (T * p, R(T::* pfn)(A)) [inline]

Инициализирующий конструктор.

Аргументы:
p
Объект, у которого нужно вызвать метод.
pfn
Указатель на вызываемый метод.

Объявления и описания членов класса находятся в файле:

Глава 9
cpp_util_2 Файлы

9.1 Файл cpp_util_2/h/cpp_util.hpp

9.1.1 Подробное описание

Общий файл для всех макросов.

Подключает файлы с определениями основных макросов.

#include <cpp_util_2/h/defs.hpp>

#include <cpp_util_2/h/detect_compiler.hpp>

9.2 Файл cpp_util_2/h/defs.hpp

9.2.1 Подробное описание

Не привязанные к компилятору макросы.

Основные макросы, которые могут использоваться в любых компиляторах.

Макросы

9.2.2 Макросы

9.2.2.1 #define CPP_UTIL_2_ASIZE(array)

Возвращает размер массива array в элементах.

9.2.2.2 #define CPP_UTIL_2_SIZEOFATTR(t, a)

Возвращает размерность атрибута attr типа type в байтах.

9.3 Файл cpp_util_2/h/detect_compiler.hpp

9.3.1 Подробное описание

Зависящие от компилятора макросы.

Макросы, имена которых для всех компиляторов остаются одинаковыми, но раскрываются по разному.

Основное назначение этих макросов – унификация и скрытие от программиста различных особенностей и/или не стандартизированных расширений C++.

Макросы

9.3.2 Макросы

9.3.2.1 #define CPP_UTIL_2_EXPORT

Указание экспортируемости.

Указывает, что класс/функция должна быть экспортируемой.

9.3.2.2 #define CPP_UTIL_2_EXPORT_FUNC_SPEC(ret_type)

Декларация экспорта функции.

В различных компиляторах ключевые слова для экспорта функции нужно указывать либо до, либо после указания типа возвращаемого значения.

Visual C++:
__declspec(dllexport) void fn() {...}

Watcom C++ & Borland C++:
void _export fn() {...}

Макрос CPP_UTIL_2_EXPORT_FUNC_SPEC подставляет соответсвующее ключевое слово для экспорта функции либо перед, либо после типа возвращаемого значения.

Пример использования:
CPP_UTIL_2_EXPORT_FUNC_SPEC(void) fn() {...}

9.3.2.3 #define CPP_UTIL_2_EXPORT_TYPE(type_qualifier)

Экспорт класса или структуры.

Аналог CPP_UTIL_2_EXPORT_FUNC_SPEC для типов.

Уст.
Использование этого макроса делает тип не видимым в визуальных средах программирования (Visual C++, Visual SlikEdit).

9.3.2.4 #define CPP_UTIL_2_EXTERNC_DECL(prefix, name, args)

Декларировать extern "C" функцию.

Уст.
Ранее использовалась для управления именами экспортируемых из DLL функций.

9.3.2.5 #define CPP_UTIL_2_EXTERNC_NAME(name)

Сформировать extern "C" имя.

Уст.
Ранее использовалась для управления именами экспортируемых из DLL функций.

9.3.2.6 #define CPP_UTIL_2_IMPORT

Указание импортируемости.

Указывает, что класс/функция должна быть импортируемой.

9.3.2.7 #define CPP_UTIL_2_IMPORT_FUNC_SPEC(ret_type)

Декларация импорта функции.

В различных компиляторах ключевые слова для импорта функции нужно указывать либо до, либо после указания типа возвращаемого значения, либо не указывать вовсе.

Visual C++:
__declspec(dllimport) void fn() {...}

Watcom C++ & Borland C++:
void _import fn() {...}

Макрос CPP_UTIL_2_IMPORT_FUNC_SPEC подставляет соответсвующее ключевое слово для экспорта функции либо перед, либо после типа возвращаемого значения.

Пример использования:
CPP_UTIL_2_IMPORT_FUNC_SPEC(void) fn() {...}

9.3.2.8 #define CPP_UTIL_2_IMPORT_TYPE(type_qualifier)

Импорт класса или структуры.

Аналог CPP_UTIL_2_IMPORT_FUNC_SPEC для типов.

Уст.
Использование этого макроса делает тип не видимым в визуальных средах программирования (Visual C++, Visual SlikEdit).

9.4 Файл cpp_util_2/h/lexcast.hpp

9.4.1 Подробное описание

Функция для конвертации значений из одного типа в другой с использованием промежуточного текстового представления.

Начиная с:
v.2.0.2

#include <sstream>

Пространства имен

9.5 Файл cpp_util_2/h/nocopy.hpp

9.5.1 Подробное описание

Класс cpp_util_2::nocopy_t.

Пространства имен

9.6 Файл cpp_util_2/h/unary_method.hpp

9.6.1 Подробное описание

Класс-обертка для вызова унарного метода объекта.

Пространства имен

9.7 Файл cpp_util_2/lexcasts/h/util.hpp

9.7.1 Подробное описание

Вспомогательные объекты для преобразования и извлечения значений.

Начиная с:
v.2.0.3

#include <cpp_util_2/h/nocopy.hpp>

#include <cpp_util_2/h/lexcast.hpp>

Пространства имен

Глава 10
cpp_util_2 Примеры

10.1 lexcast/throw/main.cpp

/*  
  Пример порождения исключения с использованием  
  cpp_util_2::lexcast().  
*/  
 
#include <map>  
#include <string>  
#include <iostream>  
#include <stdexcept>  
 
#include <cpp_util_2/h/lexcast.hpp>  
 
// Класс словаря, в котором оператор [] порождает  
// исключение, если элемент не найден по ключу.  
template< class Key, class Value, class Pred = std::less< Key > >  
class hard_map_t : public std::map< Key, Value, Pred >  
{  
  typedef std::map< Key, Value, Pred > base_type_t;  
  public :  
    hard_map_t()  
    {}  
    hard_map_t( const hard_map_t & o )  
    :  
      base_type_t( o )  
    {}  
 
    hard_map_t &  
    operator=( const hard_map_t & o )  
    {  
      base_type_t::operator=( o );  
      return *this;  
    }  
 
    Value &  
    operator[]( const Key & k )  
    {  
      typename base_type_t::iterator it = find( k );  
      if( it == end() )  
        throw std::invalid_argument(  
          std::string( "Key not found: " ) +  
          cpp_util_2::lexcast< std::string >( k ) );  
      return it->second;  
    }  
};  
 
// Проверяем работу карты с целыми ключами.  
void  
check_int()  
{  
  hard_map_t< int, int > m;  
  m.insert( hard_map_t< int, int >::value_type( 0, 0 ) );  
  m.insert( hard_map_t< int, int >::value_type( -1, -1 ) );  
  m.insert( hard_map_t< int, int >::value_type( 1, 1 ) );  
 
  try  
  {  
    std::cout << "search key: 0 => " << std::flush  
      << m[ 0 ] << std::endl;  
    std::cout << "search key: -1 => " << std::flush  
      << m[ -1 ] << std::endl;  
    std::cout << "search key: 2 => " << std::flush  
      << m[ 2 ] << std::endl;  
  }  
  catch( const std::exception & x )  
  {  
    std::cout << x.what() << std::endl;  
  }  
}  
 
// Проверяем работу карты со строковыми ключами.  
void  
check_string()  
{  
  hard_map_t< std::string, int > m;  
  m.insert( hard_map_t< std::string, int >::value_type( "A", 0 ) );  
  m.insert( hard_map_t< std::string, int >::value_type( "B", -1 ) );  
  m.insert( hard_map_t< std::string, int >::value_type( "C", 1 ) );  
 
  try  
  {  
    std::cout << "search key: A => " << std::flush  
      << m[ "A" ] << std::endl;  
    std::cout << "search key: B => " << std::flush  
      << m[ "B" ] << std::endl;  
    std::cout << "search key: D => " << std::flush  
      << m[ "D" ] << std::endl;  
  }  
  catch( const std::exception & x )  
  {  
    std::cout << x.what() << std::endl;  
  }  
}  
 
int  
main()  
{  
  check_int();  
  check_string();  
 
  return 0;  
}

10.2 lexcast/util/main.cpp

/*  
  Пример работы со средствами из cpp_util_2/lexcast/h/util.hpp.  
*/  
 
#include <map>  
#include <set>  
#include <string>  
#include <iostream>  
#include <stdexcept>  
 
#include <cpp_util_2/lexcasts/h/util.hpp>  
 
// Демонстрация работы cpp_util_2::slexcast.  
void  
slexcast_demo()  
{  
  std::string pre( "This is string with spaces." );  
  std::string post( cpp_util_2::slexcast( pre ) );  
 
  std::cout << "*** slexcast_demo:\n\tpre: "  
    << pre << "\n\tpost: " << post << "\n" << std::endl;  
}  
 
// Демонстрация преобразования в шестнадцатиричное представление.  
void  
hex_putter_demo()  
{  
  // Если тип char по умолчанию беззнаковый.  
  char c1 = 16;  
  // Если тип char по умолчанию знаковый.  
  char c2 = static_cast< char >( -3 );  
  signed char c_negative = -3;  
  unsigned char uc = 16;  
 
  short s = 16;  
  short s_negative = -3;  
  unsigned short us = 16;  
  int i = 16;  
  int i_negative = -3;  
  unsigned int ui = 16;  
  long l = 16;  
  long l_negative = -3;  
  unsigned long ul = 16;  
 
  std::cout << "*** hex_putter_demo:\n\t"  
    << (int)c1 << " " << cpp_util_2::slexcast( c1,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( c1,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( c1,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << (int)c2 << " " << cpp_util_2::slexcast( c2,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( c2,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( c2,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << (int)c_negative << " " << cpp_util_2::slexcast( c_negative,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( c_negative,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( c_negative,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << (unsigned int)uc << " " << cpp_util_2::slexcast( uc,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( uc,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( uc,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << s << " " << cpp_util_2::slexcast( s,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( s,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( s,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << s_negative << " " << cpp_util_2::slexcast( s_negative,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( s_negative,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( s_negative,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << us << " " << cpp_util_2::slexcast( us,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( us,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( us,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << i << " " << cpp_util_2::slexcast( i,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( i,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( i,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << i_negative << " " << cpp_util_2::slexcast( i_negative,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( i_negative,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( i_negative,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << ui << " " << cpp_util_2::slexcast( ui,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( ui,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( ui,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << l << " " << cpp_util_2::slexcast( l,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( l,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( l,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << l_negative << " " << cpp_util_2::slexcast( l_negative,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( l_negative,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( l_negative,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << ul << " " << cpp_util_2::slexcast( ul,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( ul,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( ul,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << 127 << " " << cpp_util_2::slexcast( 127,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( 127,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( 127,  
      cpp_util_2::lexcasts::hex_bslashx() )  
    << "\n\t"  
 
    << -127 << " " << cpp_util_2::slexcast( -127,  
      cpp_util_2::lexcasts::hex() ) << ", "  
    << cpp_util_2::slexcast( -127,  
      cpp_util_2::lexcasts::hex_0x() ) << ", "  
    << cpp_util_2::slexcast( -127,  
      cpp_util_2::lexcasts::hex_bslashx() ) << "\n"  
    << std::endl;  
}  
 
// Демонстрация преобразования из шестнадцатиричного представления в число.  
void  
hex_getter_demo()  
{  
  std::cout << "*** hex_getter_demo:" << std::endl;  
 
  std::string hex8( "f3" );  
 
  char c = cpp_util_2::lexcast< char >( hex8,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  signed char sc = cpp_util_2::lexcast< signed char >( hex8,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  unsigned char uc = cpp_util_2::lexcast< unsigned char >( hex8,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
 
  std::cout << "\n\thex8: " << hex8  
    << "\n\tchar: " << (short)c  
    << "\n\tsigned char: " << (short)sc  
    << "\n\tunsigned char: " << (unsigned short)uc  
    << std::endl;  
 
  std::string hex16( "ff5d" );  
 
  short s = cpp_util_2::lexcast< short >( hex16,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  unsigned short us = cpp_util_2::lexcast< unsigned short >( hex16,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  int i = cpp_util_2::lexcast< int >( hex16,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  unsigned int ui = cpp_util_2::lexcast< unsigned int >( hex16,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
 
  std::cout << "\n\thex16: " << hex16  
    << "\n\tshort: " << s  
    << "\n\tunsigned short: " << us  
    << "\n\tint: " << i  
    << "\n\tunsigned int: " << ui  
    << std::endl;  
 
  std::string hex32( "ffffff5d" );  
 
  int i32 = cpp_util_2::lexcast< int >( hex32,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  unsigned int ui32 = cpp_util_2::lexcast< unsigned int >( hex32,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  long l = cpp_util_2::lexcast< long >( hex32,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
  unsigned long ul = cpp_util_2::lexcast< unsigned int >( hex32,  
    cpp_util_2::lexcasts::def_putter(),  
    cpp_util_2::lexcasts::hex_getter() );  
 
  std::cout << "\n\thex32: " << hex32  
    << "\n\tint: " << i32  
    << "\n\tunsigned int: " << ui32  
    << "\n\tlong: " << l  
    << "\n\tunsigned long: " << ul  
    << std::endl;  
}  
 
// Преобразование значений контейнера с  
// использованием cpp_util_2::slexcast().  
void  
container_putter_demo()  
{  
  std::cout << "*** container_putter_demo:" << std::endl;  
 
  // Печать всех значений из массива.  
  unsigned int ui[ 8 ] = { 18, 17, 16, 15, 14, 13, 12, 10 };  
  std::cout << cpp_util_2::slexcast(  
      cpp_util_2::lexcasts::all(  
        ui, ui + ( sizeof(ui) / sizeof(ui[0]) ) ) )  
    << std::endl;  
  // То же самое, но в шестнадцатиричном виде.  
  std::cout << cpp_util_2::slexcast(  
      cpp_util_2::lexcasts::all(  
        ui, ui + ( sizeof(ui) / sizeof(ui[0]) ), " ",  
        cpp_util_2::lexcasts::hex() ) )  
    << std::endl;  
 
  // Печать всех значений вектора строк, разделяя каждое значение  
  // переводом строки.  
  std::set< std::string > ss;  
  ss.insert( "AAA" );  
  ss.insert( "CCC" );  
  ss.insert( "BBB" );  
  ss.insert( "EEE" );  
  ss.insert( "DDD" );  
#if !defined( __BORLANDC__ )  
  std::cout << cpp_util_2::slexcast(  
      cpp_util_2::lexcasts::all( ss.begin(), ss.end(), "\n" ) )  
    << std::endl;  
#endif  
 
  // Еще раз, но проще.  
  std::cout << cpp_util_2::slexcast(  
      cpp_util_2::lexcasts::all( ss, "\n" ) )  
    << std::endl;  
 
  // Отображаем каждый символ строки в шестнадцатиричном виде.  
  std::string hello( "Hello, World" );  
  std::cout << "ASCII string: " << hello  
    << "\nHex string: " << cpp_util_2::slexcast(  
      cpp_util_2::lexcasts::all( hello.begin(), hello.end(), "",  
        cpp_util_2::lexcasts::hex_bslashx() ) )  
    // Печатаем тоже самое, но проще.  
    << "\nHex string 2: "<< cpp_util_2::slexcast(  
      cpp_util_2::lexcasts::all( hello, "",  
        cpp_util_2::lexcasts::hex_bslashx() ) )  
    << std::endl;  
}  
 
int  
main()  
{  
  slexcast_demo();  
 
  hex_putter_demo();  
 
  hex_getter_demo();  
 
  container_putter_demo();  
 
  return 0;  
}

10.3 unary_method/find_if/main.cpp

/*  
  Пример поиска в списке строк элемента,  
  содержащего указанные две подстроки.  
*/  
 
#include <list>  
#include <string>  
#include <algorithm>  
#include <functional>  
#include <iostream>  
 
#include <cpp_util_2/h/unary_method.hpp>  
 
class pred_t  
{  
  public :  
    pred_t(  
      // Первая искомая строка.  
      const std::string & first,  
      // Вторая искомая строка.  
      const std::string & second );  
 
    // Будет вызываться для каждого очередного  
    // элемента списка.  
    // Возвращает true, если обе подстроки найдены.  
    bool  
    next( const std::string & what ) const;  
 
  private :  
    std::string m_first;  
    std::string m_second;  
};  
 
pred_t::pred_t(  
  const std::string & first,  
  const std::string & second )  
:  
  m_first( first )  
, m_second( second )  
{  
}  
 
bool  
pred_t::next( const std::string & what ) const  
{  
  return ( std::string::npos != what.find( m_first )  
    &&  std::string::npos != what.find( m_second ) );  
}  
 
void  
search(  
  // Где искать.  
  const std::list< std::string > & where,  
  // Что искать.  
  const std::string & first,  
  const std::string & second )  
{  
  std::cout << "search (" << first << "," << second << "): ";  
 
  // Ищем элемент.  
  pred_t pred( first, second );  
  std::list< std::string >::const_iterator  
  it( std::find_if( where.begin(), where.end(),  
      cpp_util_2::unary_method(  
        // У этого объекта...  
        &pred,  
        // ... будет вызван метод.  
        &pred_t::next ) ) );  
  if( it != where.end() )  
    std::cout << "found: " << *it << std::endl;  
  else  
    std::cout << "not found" << std::endl;  
}  
 
int  
main()  
{  
  std::list< std::string > l;  
  l.push_back( "4444 3333 2222 777" );  
  l.push_back( "333 7777" );  
  l.push_back( "666 444 111 666" );  
  l.push_back( "7777777" );  
  l.push_back( "22 333 777 8888 444" );  
  l.push_back( "55555" );  
 
  search( l, "333", "888" );  
  search( l, "333", "111" );  
 
  return 0;  
}

10.4 unary_method/for_each_find_min_max/main.cpp

/*  
  Пример поиска в списке строк с минимальной и максимальной длиной.  
*/  
 
#include <list>  
#include <string>  
#include <algorithm>  
#include <iostream>  
 
#include <cpp_util_2/h/unary_method.hpp>  
 
class finder_t  
{  
  public :  
    // Будет вызываться для каждого очередного  
    // элемента списка.  
    void  
    next( const std::string & what );  
 
    const std::string &  
    min() const;  
 
    const std::string &  
    max() const;  
 
  private :  
    std::string m_min;  
    std::string m_max;  
};  
 
void  
finder_t::next( const std::string & what )  
{  
  // Считаем, что в списке нет пустых строк,  
  // поэтому пустой m_min может быть только  
  // в начале поиска.  
  if( m_min.empty()  
    || m_min.length() > what.length() )  
  {  
    m_min = what;  
  }  
 
  if( m_max.length() < what.length() )  
    m_max = what;  
}  
 
const std::string &  
finder_t::min() const  
{  
  return m_min;  
}  
 
const std::string &  
finder_t::max() const  
{  
  return m_max;  
}  
 
// Найти самую короткую и самую длинную строки.  
void  
find(  
  const std::list< std::string > & where,  
  std::string & min,  
  std::string & max )  
{  
  finder_t finder;  
  std::for_each( where.begin(), where.end(),  
    cpp_util_2::unary_method(  
      // У этого объекта...  
      &finder,  
      // ... будет вызываться метод next.  
      &finder_t::next ) );  
  min = finder.min();  
  max = finder.max();  
}  
 
int  
main()  
{  
  std::list< std::string > l;  
  l.push_back( "4444" );  
  l.push_back( "333" );  
  l.push_back( "666666" );  
  l.push_back( "7777777" );  
  l.push_back( "22" );  
  l.push_back( "55555" );  
 
  std::string min, max;  
  find( l, min, max );  
 
  std::cout << "min: " << min  
    << ", max: " << max  
    << std::endl;  
 
  return 0;  
}

10.5 unary_method/for_each_modify/main.cpp

/*  
  Пример изменения каждого элемента списка строк.  
*/  
 
#include <list>  
#include <string>  
#include <algorithm>  
#include <functional>  
#include <iostream>  
 
#include <cpp_util_2/h/unary_method.hpp>  
 
class modificator_t  
{  
  public :  
    modificator_t(  
      // Добавляемый к строке префикс.  
      const std::string & prefix,  
      // Добавляемый к строке суффикс.  
      const std::string & suffix );  
 
    // Будет вызываться для каждого очередного  
    // элемента списка.  
    void  
    next( std::string & what ) const;  
 
  private :  
    std::string m_prefix;  
    std::string m_suffix;  
};  
 
modificator_t::modificator_t(  
  const std::string & prefix,  
  const std::string & suffix )  
:  
  m_prefix( prefix )  
, m_suffix( suffix )  
{  
}  
 
void  
modificator_t::next( std::string & what ) const  
{  
  what.insert( 0, m_prefix );  
  what += m_suffix;  
}  
 
// Печатает очередной элемент списка.  
void  
printer( const std::string & a )  
{  
  std::cout << a << " ";  
}  
 
int  
main()  
{  
  std::list< std::string > l;  
  l.push_back( "4444" );  
  l.push_back( "333" );  
  l.push_back( "666666" );  
  l.push_back( "7777777" );  
  l.push_back( "22" );  
  l.push_back( "55555" );  
 
  // Печатаем исходный список.  
  std::for_each( l.begin(), l.end(), printer );  
  std::cout << std::endl;  
 
  // Модифицируем все элементы.  
  modificator_t m( "-=: ", " :=-" );  
  std::for_each( l.begin(), l.end(),  
    cpp_util_2::unary_method(  
      // У этого объекта...  
      &m,  
      // ... будет вызван метод.  
      &modificator_t::next ) );  
 
  // Печатаем полученный список.  
  std::for_each( l.begin(), l.end(), printer );  
  std::cout << std::endl;  
 
  return 0;  
}

Глава 11
cpp_util_2 Тематические описания

11.1 cpp_util_2: Обертки для вызова унарных методов объектов

11.1.1 Введение

Необходимость в классах cpp_util_2::unary_method_t (cpp_util_2::const_unary_method_t) возникла при очередном использовании функции std::for_each. Был список std::string и был класс у которого нужно было вызвать метод для каждого из элементов список. Простое решение:
class actor_t  
{  
  public :  
    void  
    some_method( const std::string & o );  
    ...  
};  
 
void  
initialize_actor  
  ( actor_t & actor,  
    const std::list< std::string > & l )  
{  
  for( std::list< std::string >::const_iterator  
    it = l.begin(), it_end = l.end();  
    it != it_end;  
    ++it )  
  {  
    actor.some_method( *it );  
  }  
}

хотелось заменить на использование std::for_each:
void  
initialize_actor  
  ( actor_t & actor,  
    const std::list< std::string > & l )  
{  
  std::for_each( l.begin(), l.end(), ... );  
}

С помощью STL это можно было бы сделать, например, так:
void  
initialize_actor  
  ( actor_t & actor,  
    const std::list< std::string > & l )  
{  
  std::for_each  
    ( l.begin(),  
      l.end(),  
      std::bind1st  
      ( std::mem_fun( &actor_t::some_method ),  
        &actor ) );  
}

Но здесь возникают сразу две проблемы:

Проблему с построением ссылки на ссылку можно попробовать обойти с помощью boost::bind1st:
void  
initialize_actor  
  ( actor_t & actor,  
    const std::list< std::string > & l )  
{  
  std::for_each  
    ( l.begin(),  
      l.end(),  
      boost::bind1st  
      ( std::mem_fun( &actor_t::some_method ),  
        &actor ) );  
}

Но и здесь нашлись подводные камни: компилятор Visual C++ выдавал следующую диагностику:
test\unary_method\boost_way\for_each.cpp(64) : error C2782: ’boost::binder1st<Op  
eration> boost::bind1st(Operation &,boost::call_traits<Operation>::param_type)’  
: template parameter ’Operation’ is ambiguous  
        could be ’actor_t *’  
        or       ’std::const_mem_fun1_t<_Result,_Ty,_Arg>’  
        with  
        [  
            _Result=void,  
            _Ty=actor_t,  
            _Arg=const std::basic_string<char,std::char_traits<char>,std::alloca  
tor<char>> &  
        ]

Хотя другие компиляторы (Borland C++ 5.6, MinGW 3.0.0) успешно компилировали данный код. Visual C++ 6.0 так же выдавал ошибки, но свои:
test\unary_method\boost_way\for_each.cpp(64) : error C2784: ’class std::mem_fun_  
t<_R,_Ty> __cdecl std::mem_fun(_R (__thiscall _Ty::*)(void))’ : could not deduce  
 template argument for ’<Unknown>’ from ’void (__thiscall actor_t::*)(const clas  
s std::basic_string<char,struct std::char_traits<char>,class std::allocator<char  
> > &) const’

А основная проблема была в том, что нужно было использовать как раз Visual C++ версий 6.0 и 7.0.

Кроме того, конструкция:
boost::bind1st  
  ( std::mem_fun( &actor_t::some_method ),  
    &actor )

для вызова метода объекта выглядит не сильно понятной с первого взгляда.

Из-за всего вышеизложенного были созданы классы cpp_util_2::unary_method_t и cpp_util_2::const_unary_method_t, которые позволили решить эту же задачу под всеми имеющимися у меня компиляторами:
void  
initialize_actor  
  ( actor_t & actor,  
    const std::list< std::string > & l )  
{  
  std::for_each  
    ( l.begin(),  
      l.end(),  
      cpp_util_2::unary_method  
        ( &actor,  
        &actor_t::some_method ) );  
}

11.1.2 Недостаток

По сравнению с реализацией boost::bind1st классы cpp_util_2::unary_method_t и cpp_util_2::const_unary_method_t менее эфективны, т.к. при вызове метода объекта используется вспомогательная функция, которая получает дополнительный аргумент-указатель. Этот аргумент нигде не используется, поэтому хороший оптимизирующий компилятор, наверное, сможет простроить не менее эффективный код по сравнению с boost::bind1st. Но если оптимизатор не сможет игнорировать использование этого параметра, то реализация unary_method_t должна проигрывать реализации boost::bind1st. Но на современной технике и на очень больших количествах вызовах этот проигрыш вряд ли составит даже миллисекунды.

11.2 cpp_util_2: Средства lexcasts

11.2.1 Введение

Идея создания средств cpp_util_2::lexcasts появилась после знакомства с проектом boost::lexical_cast. Реализация lexical_cast в boost не устраивала меня по нескольким причинам:

Между тем, сама идея средств boost::lexical_cast показалась мне очень интересной и полезной. Поэтому я решил реализовать подобные средства с учетом собственных идей и предпочтений в проекте cpp_util_2.

11.2.2 Назначение

Средства cpp_util_2::lexcasts предназначены для удобного преобразования различных значений в строку или из строки. Например, при обработке ошибок часто возникает задача преобразовать в строку одно целочисленное значение. Причем в десятичном и шестнадцатиричном виде:
void  some_func( unsigned int param )  
{  
  ...  
  if( some_error )  
  {  
    char sz[ 48 ];  
    sprintf( sz, "%u (0x%x)", param, param );  
    throw std::invalid_argument(  
      std::string( "Invalid param: " ) + sz );  
  }  
}

Либо, аналогичный фрагмент можно было бы переписать с использованием std::ostringstream:
void  some_func( unsigned int param )  
{  
  ...  
  if( some_error )  
  {  
    std::ostringstream errs;  
    errs << param << std::hex << param;  
    throw std::invalid_argument(  
      std::string( "Invalid param: " ) + errs.str() );  
  }  
}

Это уже лучше, чем с использованием sprintf, но все равно не удобно – вместо одного оператора throw приходится писать три оператора.

Применение cpp_util_2::slexcast() позволяет использовать только один оператор throw:
void  some_func( unsigned int param )  
{  
  ...  
  if( some_error )  
    throw std::invalid_argument(  
      std::string( "Invalid param: " ) +  
      cpp_util_2::slexcast( param ) + " " +  
      cpp_util_2::slexcast( param,  
        cpp_util_2::lexcasts::hex_0x() ) );  
}

11.2.3 Принцип работы

Принцип работы функций cpp_util_2::lexcast(), cpp_util_2::slexcast() очень простой: создается объект std::stringstream в который сначала "сдвигается" (<<) исходное значение, а затем "выдвигается" (>>) результирующее значение. Т.е. вызов cpp_util_2::lexcast<B>(a) можно представить в виде:
std::stringstream ss;  
ss << a;  
ss.seekg( 0 );  
B b;  
ss >> b;

В случае использования Putter-ов и Getter-ов сдвиги в/из std::stringstream осуществляют Putter-ы и/или Getter-ы. Т.е. для случая cpp_util_2::lexcast<B>(a, p, g):
std::stringstream ss;  
p( ss, a );  
ss.seekg( 0 );  
B b;  
g( ss, b );

11.2.4 Преобразование сложных типов

11.2.4.1 Структуры и классы

Если для структуры или класса определен оператор сдвига в std::ostream, то cpp_util_2::lexcast() позволяет преобразовать объект этого класса в строку. Например:
struct  my_struct_t  
{  
  int m_a;  
  std::string m_b;  
  float m_c;  
};  
 
std::ostream &  
operator<<( std::ostream & to, const my_struct_t & o )  
{  
  return ( to << "my_struct_t{ m_a: " << o.m_a  
    << ", m_b: " << o.m_b  
    << ", m_c: " << o.m_c << "}" );  
}

Но здесь есть подводный камень: стандартный operator>>(std::istream &, std::string &) считывает значение в строку до первого пробела. Поэтому выполнение:
my_struct_t a;  
std::string b( cpp_util_2::lexcast< std::string >( a ) );

приведет к тому, что b будет равно "my_struct_t{".

Для того, чтобы результирующая строка содержала все представление объекта my_struct_t необходимо использовать функцию cpp_util_2::slexcast(). Эта функция извлекает из промежуточного std::stringstream все содержимое не обращаясь к operator>>(std::istream &, std::string &).

11.2.4.2 Контейнеры

Иногда желательно преобразовать в строку содержимое какого-то контейнера. Для этих целей предназначены функции cpp_util_2::lexcats::all(). Например, если требуется отобразить все элементы std::list< int >:
std::list< int > l;  
...  
std::string result( cpp_util_2::slexcast( cpp_util_2::lexcasts::all( l, " " ) ) );

В этом случае в строку помещаются все значения, находящиеся в l, каждое значение разделяется пробелом. После последнего значения пробел не печается.

В функцию cpp_util_2::lexcasts::all() можно передать объект Putter. Например, для того, чтобы отобразить все значения из l в шестнадцатиричном виде можно написать:
std::string result( cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( l, " ",  
    cpp_util_2::lexcasts::hex() ) ) );

Иногда возникает необходимость отобразить все содержимое std::string в виде шестнадцатиричного представления каждого из символов в C-формате (т.е. с использованием префикса \x). Для этого можно воспользоваться конструкцией:
std::string a( ... );  
std::string result( cpp_util_2::slexcast(  
  cpp_util_2::lexcasts::all( a,  
    "" /* Это не пробел, а пустая строка! */,  
    cpp_util_2::lexcasts::hex_bslashx() ) ) );

С функции cpp_util_2::lexcasts::all() можно использовать итераторы. Например, для того, чтобы отобразить все элементы массива:
int array[ 10 ] = { ... };  
std::cout << cpp_util_2::slexcast( cpp_util_2::lexcasts::all(  
  array, array + ( sizeof( array ) / sizeof( array[ 0 ] ) ), " " ) );

Или все элементы множества, большие указанного значения:
std::set< int > s;  
...  
std::cout << cpp_util_2::slexcast( cpp_util_2::lexcasts::all(  
  s.upper_bound( k ), s.end(), "\n" ) );

11.2.4.3 Собственные Putter-ы

Иногда требуется создать собственный объект Putter. Например в следующих случаях:

1. Класс, который требуется преобразовать определен в чужом namespace. И в этом namespace для класса не определен оператор сдвига в std::ostream. Т.е.
namespace ns1  
{  
  class useful_t { ... };  
}  
 
namespace ns2  
{  
  void  process( const ns1::useful_t & o )  
  {  
    // ОШИБКА: не будет скомпилировано!  
    std::string s( cpp_util_2::slexcast( o ) );  
  }  
}

Решением может быть:
namespace ns2  
{  
  struct  useful_putter  
  {  
    void  
    operator()( std::ostream & to, const ns1::useful_t & o )  
    {  
      ...  
    }  
  };  
 
  void  process( const ns1::useful_t & o )  
  {  
    std::string s( cpp_util_2::slexcast( o, useful_putter() ) );  
  }  
}

Либо:
namespace ns2  
{  
  void  
  useful_putter( std::ostream & to, const ns1::useful_t & o )  
  {  
    ...  
  }  
 
  void  process( const ns1::useful_t & o )  
  {  
    std::string s( cpp_util_2::slexcast( o, useful_putter ) );  
  }  
}

2. Необходимо отображать не весь объект, а только его часть. Например, если необходимо отобразить только значение элемента std::map, но не ключ этого элемента. Решением может быть:
typedef std::map< int, std::string >  str_by_int_map_t;  
 
void  
value_putter( std::ostream & to, const str_by_int_map_t::value_type & o )  
{  
  to << o.second;  
}  
 
// Отображение всех значений всех элементов, чей ключ больше указанного.  
void  
show_values_for_greater_keys(  
  int k,  
  const str_by_int_map_t & m )  
{  
  std::cout << cpp_util_2::slexcast( cpp_util_2::lexcasts::all(  
    m.upper_bound( k ), m.end(), "\n", value_putter ) )  
    << std::endl;  
}

11.3 cpp_util_2: Список модификаций.

11.3.1 2.1.0

2004.02.18

Преобразование и упрощение функций cpp_util_2::lexcast(), cpp_util_2::slexcast().

Преобразование и упрощение средств из пространства имен cpp_util_2::lexcasts:

Добавлен класс cpp_util_2::lexcasts::def_putter.

11.3.2 2.0.3

2004.01.11, 2004.01.14

Добавлены функции cpp_util_2::slexcast().

Добавлены функции cpp_util_2::lexcasts::all(), упрощающие преобразование векторов и контейнеров.

Добавлены классы cpp_util_2::lexcasts::hex_t, cpp_util_2::lexcasts::prefixed_hex_t и функции cpp_util_2::lexcasts::hex_0x(), cpp_util_2::lexcasts::hex_bslashx(), которые упрощают преобразование значений в шестнадцатиричное представление.

Добавлены классы cpp_util_2::putter_t, cpp_util_2::getter_t и несколько перегруженных вариантов функции cpp_util_2::lexcast().

Добавлено пространство имен cpp_util_2::lexcasts.

Добавлен класс cpp_util_2::lexcasts::string_getter_t и функция cpp_util_2::lexcasts::string_getter().

11.3.3 2.0.2

2003.12.27

Добавлена функция cpp_util_2::lexcast().

11.3.4 2.0.1

2003.11.20

Добавлены классы cpp_util_2::unary_method_t, cpp_util_2::const_unary_method_t.

11.4 Список устаревших определений и описаний

Член CPP_UTIL_2_EXPORT_TYPE(type_qualifier)
Использование этого макроса делает тип не видимым в визуальных средах программирования (Visual C++, Visual SlikEdit).

Член CPP_UTIL_2_EXTERNC_DECL(prefix, name, args)
Ранее использовалась для управления именами экспортируемых из DLL функций.

Член CPP_UTIL_2_EXTERNC_NAME(name)
Ранее использовалась для управления именами экспортируемых из DLL функций.

Член CPP_UTIL_2_IMPORT_TYPE(type_qualifier)
Использование этого макроса делает тип не видимым в визуальных средах программирования (Visual C++, Visual SlikEdit).
Hosted by uCoz