Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> extern и enum 
V
    Опции темы
azesmcar
Дата 4.5.2009, 19:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата(mes @  4.5.2009,  19:20 Найти цитируемый пост)
не отказался от примера такой задачи


Код

namespace headers {
    enum header_enum {
        header_1,
        header_2,
        header_3,
        header_size //must be last
    };
};

int arr[headers::header_size];

void set_header(headers::header_enum en, int val)
{
    arr[en] = val;
}

int main()
{
    set_header(headers::header_1, 1);
    set_header(headers::header_2, 3);
    set_header(5, 1); //ошибка - компайл тайм проверка типа сработала
}


Например что-то вроде этого. Программа не вылетит рантайм, потому что пользователь передал функции неверный тип а выдаст компайл тайм ошибку. Разумеется это упрощенный пример.

Это сообщение отредактировал(а) azesmcar - 4.5.2009, 19:37
PM   Вверх
J0ker
Дата 4.5.2009, 19:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 9
Всего: 14



Цитата(mes @  4.5.2009,  19:20 Найти цитируемый пост)
Обычно enum использую для битовых комбинаций флагов,

магнитне бури
мысли плохо считываются



--------------------
user posted image
PM MAIL   Вверх
mes
Дата 4.5.2009, 21:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(J0ker @  4.5.2009,  18:37 Найти цитируемый пост)
Цитата

Обычно enum использую для битовых комбинаций флагов,


мысли плохо считываются

как константы обозначающие бит или битовую комбинацию.

Цитата(azesmcar @  4.5.2009,  18:35 Найти цитируемый пост)
Например что-то вроде этого

а нет чего нибудь более  "показательного"  или "применительного" ? 



Это сообщение отредактировал(а) mes - 4.5.2009, 21:13


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 4.5.2009, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

а нет чего нибудь более  "показательного"  или "применительного" ? 

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

mes

Еще как вариант - перегрузка
Код

enum kind_of_value
{
    kind_of_value1,
    kind_of_value2,
    kind_of_value3
};

void set_value(const std::string& val) {
    /* ... */
}
void set_value(int val) {
    /* ... */
}
void set_value(kind_of_value val) {
    /* ... */
}

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


Это сообщение отредактировал(а) azesmcar - 4.5.2009, 21:46
PM   Вверх
azesmcar
Дата 4.5.2009, 21:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Вот еще пример, допустим мне нужно хранить значения своего enum в векторе. Можно специализировать вектор потому что 2 бита для хранения моего enum-а мне вполне достаточно. Это может понадобится при передаче большого количества данных по сети например.

Код

enum my_enum
{
    value1, //binary 00
    value2, //binary 01
    value3, //binary 10
    value4  //binary 11
};

template <>
class std::vector<my_enum>
{
    /* ... */
};

без типа такого сделать не выйдет smile
PM   Вверх
mes
Дата 4.5.2009, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(azesmcar @  4.5.2009,  20:32 Найти цитируемый пост)
А этот не применителен? 

ага пример с header не очень, 
так например массив, к которому не нужен динамический доступ, лучше заменить структорой,
также и для функции не вижу реального примера, когда лучше огранить enum`ом как в Вашем примере.
диапазон  намного эффективнее контролировать например так:
Код

template <int n>set_value_for_header (int value) {STATIC_CHECK(n<sizeof...); ... }


Цитата(azesmcar @  4.5.2009,  20:32 Найти цитируемый пост)
Еще как вариант - перегрузка

вот тут надо подумать - попробую подобрать задачу под такое применение.


azesmcar, спасибо за старания.  smile

Добавлено через 4 минуты и 18 секунд
Цитата(azesmcar @  4.5.2009,  20:57 Найти цитируемый пост)
Можно специализировать вектор 

Цитата(mes @  4.5.2009,  18:20 Найти цитируемый пост)
употребление в шаблонах отдельная тема.

и выгоду в этом разделе я не подвергаю сомнению.
меня больше интересует случай, про
Цитата(mes @  4.5.2009,  16:16 Найти цитируемый пост)
преимущество, которое дается при создании переменнной типа енум ?





--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 4.5.2009, 22:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



mes

Цитата

так например массив, к которому не нужен динамический доступ, лучше заменить структорой,

Может и понадобиться, смотря какая задача. Если заголовок какого нибудь протокола - динамический доступ наверняка будет нужен (котрольные суммы, итд, итп...)
Цитата

диапазон  намного эффективнее контролировать например так:

Можно так - согласен
Эффективнее? вот тут непонятно.. О какой эффективности идет речь если мы говорим о компайл тайм проверке? smile

Цитата

вот тут надо подумать - попробую подобрать задачу под такое применение.

как вариант со специализацией я привел, насчет перегрузки - подумаю какую нибудь конкретную задачу smile

Добавлено через 2 минуты и 36 секунд
Цитата

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

а..видимо не заметил, прошу прощения.
PM   Вверх
mes
Дата 4.5.2009, 22:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(azesmcar @  4.5.2009,  21:20 Найти цитируемый пост)
Может и понадобиться, смотря какая задача. Если заголовок какого нибудь протокола - динамический доступ наверняка будет нужен (котрольные суммы, итд, итп...)

но пока я не вижу, что приведенное решение хорошо справляется с задачей. smile

Цитата(azesmcar @  4.5.2009,  21:20 Найти цитируемый пост)
Эффективнее? вот тут непонятно.. О какой эффективности идет речь если мы говорим о компайл тайм проверке? smile

Разумеется не о скорости, а о качестве и возможностях проверки. Последний случай (стат. проверка в шабл.), грубо говоря, к примеру, нас освобождает от запоминания того, что енумы хидера должны идти по порядку. smile






--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 4.5.2009, 22:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Я немного доработал свой первый пример, попытался сделать его нагляднее. Получился почему-то генератор майм заголовков smile 
Посмотрим на этот код к примеру (не надо его критиковать smile быстро написал для примера)
Код

class mime
{
public:
    enum header
    {
        content_type,
        content_disposition,
        content_length,
        headers_size //must be last
    };
public:
    void set_header(header e, const std::string& val)
    {
        mime_[e] = val;
    }

    std::string generate() const {
        std::ostringstream stream;
        for (int i = content_type; i < headers_size; ++i)
        {
            stream << header_texts[i] << ": " << mime_[i] << std::endl;
        }
        return stream.str();
    }
private:
    static const char* header_texts[headers_size];

    std::string mime_[headers_size];
};

const char* mime::header_texts[mime::headers_size] = {
    "Content-Type",
    "Content-Disposition",
    "Content-Length"
};

int main()
{
    mime v;
    v.set_header(mime::content_type, "text/html");
    v.set_header(mime::content_disposition, "attachment");
    v.set_header(mime::content_length, "100");
    std::cout << v.generate();
}

посмтрим что он нам дает. 
функции set_header нельзя передать неправильное значение (если не извращатся с Си стайл cast -ом и другими методами, но это не в счет). Если заменить тип на int, получится что в него можно передать все что угодно. Тогда ставим ваш STATIC_CHECK - кстати а как он выглядет взглянуть можно? В принципе можно конечно, но зачем писать то что должен сделать компилятор за вас?

Я так понимаю STATIC_CHECK это описанный у Александреску макрос? Но я не понимаю как он применителен здесь? Функция получает параметр..как будете проверять? Давайте поступим проще smile 
измените мой код так, чтобы он работал с int без потери безопасности

Это сообщение отредактировал(а) azesmcar - 4.5.2009, 23:27
PM   Вверх
J0ker
Дата 4.5.2009, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 986
Регистрация: 17.9.2008

Репутация: 9
Всего: 14



Цитата(mes @  4.5.2009,  21:13 Найти цитируемый пост)
как константы обозначающие бит или битовую комбинацию.

да понял я
это было пояснение к предыдущему


--------------------
user posted image
PM MAIL   Вверх
mes
Дата 5.5.2009, 01:08 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(azesmcar @  4.5.2009,  21:59 Найти цитируемый пост)
Давайте поступим проще smile 
измените мой код так, чтобы он работал с int без потери безопасности

видно опять невнимательно читали, или я плохо объяснял свою позицию smile


для начала несколько цитат:  
Цитата(mes @  4.5.2009,  18:20 Найти цитируемый пост)
Но, наверно, я не сталкивался с такими задачами, когда мне нужен был именно контроль по enum-типу и  при  этом хватало бы гарантий которые он дает.
(старался типобезопасность обеспечить через более "надежные" типы).

Цитата(mes @  4.5.2009,  14:49 Найти цитируемый пост)
лучше (имхо) объявлять переменные не  enum типа,  а простого целочисленного.
А енумы использовать как набор констант (для сравнения или присваивания).  smile 

Цитата(mes @  4.5.2009,  21:11 Найти цитируемый пост)
не вижу преимущество, которое дается при создании переменнной типа енум ?


Я вот даже не знаю как бы поточней выразить свою мысль.Я считаю енумы "слабыми" среди типов и их ниша именно константы (с которой они справляются очень успешно).
Ваш пример только подверждает мою позицию. Переменная e, косвенно попадающая под наше рассмотренние, нужна лишь для "переноса" константы.
Никаких операций с ней не проводится. Я подумаю, и позже постараюсь поясней выразится.

P.S.

Цитата(azesmcar @  4.5.2009,  21:59 Найти цитируемый пост)
STATIC_CHECK это описанный у Александреску макрос? 

ага из этой категории :
http://www.solarix.ru/for_developers/cpp/s...assertion.shtml

вот переписываю под int (просто для сравнения,так как Ваш пример меня в принципе устраивает, и если бы я и стал менять то не в сторону inta , a в сторорну структур )
Код

template<int n>void set_header(const std::string& val)
{
   STATIC_CHECK (n<headers_size);
   STATIC_CHECK (n!=content_length); // для демонстрации преимуществ запрет на изменение длины контента.
   mime_[n] = val;
}

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

http://forum.vingrad.ru/index.php?showtopi...t&p=1857876
http://forum.vingrad.ru/index.php?showtopi...t&p=1860045




Это сообщение отредактировал(а) mes - 5.5.2009, 01:12


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 5.5.2009, 09:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

Я вот даже не знаю как бы поточней выразить свою мысль.Я считаю енумы "слабыми" среди типов и их ниша именно константы (с которой они справляются очень успешно).
Ваш пример только подверждает мою позицию. Переменная e, косвенно попадающая под наше рассмотренние, нужна лишь для "переноса" константы.
Никаких операций с ней не проводится. Я подумаю, и позже постараюсь поясней выразится.

Согласен smile 
енумы слабые, я не спорю, но это то что дал нам С++, не выбрасывать же на свалку нужную вещь smile 
Цитата

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

речь вовсе не об этом, просто я хочу сказать что в некоторых ситуациях переменная типа енум вещь нужная. И пытаюсь привести пример (вы же сами сказали что не отказались бы от такого примера smile )
Я не спорю, пока просто пытаюсь привести наглядный пример.
Цитата

вот переписываю под int (просто для сравнения,так как Ваш пример меня в принципе устраивает, и если бы я и стал менять то не в сторону inta , a в сторорну структур )

отлично smile это нам и нужно. Пример принят, а вот теперь можно уже поговорить (поспорить) о том как правильнее.
Для начала - оба варианта
Код

template<int n>void set_header(const std::string& val)
{
   STATIC_CHECK (n<headers_size);
   STATIC_CHECK (n!=content_length); // для демонстрации преимуществ запрет на изменение длины контента.
   mime_[n] = val;
}

и
Код

void set_header(header e, const std::string& val)
{
   mime_[e] = val;
}

и так, попробую привести все достоинства и недостатки этого решения

Решение с помощью STATIC_CHECK.
Недостатки
  • Приходится писать лишний код
  • Для каждого типа используемого енума будет сгенерирована отдельная функция
  • Функция обязательно должна быть определена в заголовке (экспорт шаблонов я по понятным причинам игнорирую  smile  )
  • Стиль вызова функции изменяется на немного необычный. 
  • Вызвать функцию динамически уже не получится, например итеративный вызов функции для всех заголовков будет невозможен
Достинства
  • Возможность писать другие компайл-тайм проверки (типа приведенного примера)
больше достоинств на ум не приходит, допишите пожалуйста для полноты картины, я потом продолжу smile

В некоторых ситуациях ваш вариант был бы идеален, и вообще шаблоны дают практически безграничные возможности компайл-тайм проверок. Но давайте поговорим в рамках данной задачи и ее требований. Добавим вот такую функцию smile
Код

void load_headers(const std::string& mime_headers) /* throw(std::invalid_arguments) */
{
    /* mime_headers parse */
    for ( /* ... */ )
    {
        set_header((header)h, v);
    }
}

будем не только генерировать заголовки, но и загружать их. Допустим в функции set_header не примитивное присваивание а сложные ран-тайм проверки на соответствие значения стандарту RFC, так что функция нам нужна.

Это сообщение отредактировал(а) azesmcar - 5.5.2009, 09:17
PM   Вверх
mes
Дата 5.5.2009, 10:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(azesmcar @  5.5.2009,  08:00 Найти цитируемый пост)
Пример принят, а вот теперь можно уже поговорить (поспорить) о том как правильнее.

Придерживаюсь вашего мнения и поэтому перед приведением примера, сделал замечание :
Цитата(mes @  5.5.2009,  00:08 Найти цитируемый пост)
вот переписываю под int (просто для сравнения,так как Ваш пример меня в принципе устраивает, и если бы я и стал менять то не в сторону inta ....


Цитата(azesmcar @  5.5.2009,  08:00 Найти цитируемый пост)
речь вовсе не об этом, просто я хочу сказать что в некоторых ситуациях переменная типа енум вещь нужная.

абсолютно согласен, енум полезная и удобная штука.
Цитата(mes @  5.5.2009,  00:08 Найти цитируемый пост)
их ниша именно константы (с которой они справляются очень успешно).

Цитата(azesmcar @  5.5.2009,  08:00 Найти цитируемый пост)
И пытаюсь привести пример 

Еще раз спасибо за дискуссию smile

Цитата(azesmcar @  5.5.2009,  08:00 Найти цитируемый пост)
вы же сами сказали что не отказались бы от такого примера 

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

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

Вот например мой условный пример, в котором рабочая переменная int; и делать ее енумом не даст никаких преимуществ.
Код


class A
{
    public:
      enum EStat { eUndefined, e1, e2, e3, eLast };

      EStat Stat () const       { return static_cast<EStat> (m_stat); }
      void SetStat (EStat stat) { if (eUndefined && stat<eLast) m_stat=stat;
                                  else m_stat= eUndefined; }

      void CircuteNext  ()  { if (m_stat != eUndefined) if (++m_stat==eLast) m_stat=e1; }
      void CircutePrev  ()  { if (m_stat != eUndefined) if (--m_stat==eUndefined) m_stat=eLast-1; }


    private:
      int m_stat;
};

этот пример отражает мой взгляд на область применения enuma. 



Это сообщение отредактировал(а) mes - 5.5.2009, 10:02


--------------------
PM MAIL WWW   Вверх
azesmcar
Дата 5.5.2009, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


uploading...
****


Профиль
Группа: Участник Клуба
Сообщений: 6291
Регистрация: 12.11.2004
Где: Армения

Репутация: 52
Всего: 211



Цитата

вот переписываю под int (просто для сравнения,так как Ваш пример меня в принципе устраивает, и если бы я и стал менять то не в сторону inta ....

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

Цитата

Еще раз спасибо за дискуссию smile

И вам спасибо за грамотную и обоснованную дискуссию smile

Цитата

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

Может я не совсем верно понял какой именно пример интересует smile
Я понял так что вам хотелось бы взглянуть на пример где используется переменная типа енум вообще, и где она имеет смысл и заменив ее на инт мы что-то потеряем.

Цитата

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

задачие разные бывают smile 
Цитата

Вот например мой условный пример, в котором рабочая переменная int; и делать ее енумом не даст никаких преимуществ.

не то что не даст преимуществ smile тут самое место типу инт. Так как с енумом вы даже ++ не сможете сделать.
но это уже другой пример.

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

Это сообщение отредактировал(а) azesmcar - 5.5.2009, 10:49
PM   Вверх
mes
Дата 5.5.2009, 14:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(azesmcar @  5.5.2009,  09:48 Найти цитируемый пост)
Может я не совсем верно понял какой именно пример интересует smile
Я понял так что вам хотелось бы взглянуть на пример где используется переменная типа енум вообще, и где она имеет смысл и заменив ее на инт мы что-то потеряем.

не совсем.. пример, где удобно применить переменную типа енум и это даст нам пользу.
Пока лишь пример где такая переменная просто "транспортирует" значение - хотя может именно в этом и заключается ее смысл, а я предъявлял к ней большие требования. smile

Цитата(azesmcar @  5.5.2009,  09:48 Найти цитируемый пост)

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

Да, с учетом всех вышеизложенных пояснений к моему взгляду . smile

Цитата(azesmcar @  5.5.2009,  09:48 Найти цитируемый пост)
да, но со структурами мы потеряем возможность итерации, что может понадобиться в рамках задачи.

не потеряет smile
Вот "исправленный" на скорую руку пример (хотя чего то в нем не хватает, но выполняет ту же задачу что и в приведенном Вами примеров, но без участия енума в логике. )

Код

class mime
{
    struct SHeader { std::string Data; };

    enum  { HeadersSize = 3 };
    SHeader Headers [HeadersSize];

    static const char* header_texts[HeadersSize];

public:
    SHeader& ContentType ()        { return Headers[0]; }
    SHeader& ContentDisposition () { return Headers[1]; }
    SHeader& ContentLength ()      { return Headers[2]; }

    std::string generate ()
    {
        std::ostringstream stream;
        for (int i = 0; i < HeadersSize; ++i)
            stream << header_texts[i] << ": " << Headers[i].Data << std::endl;
        return stream.str();
    }
};

const char* mime::header_texts[mime::HeadersSize] = {
    "Content-Type",
    "Content-Disposition",
    "Content-Length"
};

и из двух направлений решения задачи (с енумом и без) я склоняюсь к последнему smile

Это сообщение отредактировал(а) mes - 5.5.2009, 14:07


--------------------
PM MAIL WWW   Вверх
Страницы: (3) Все 1 [2] 3 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

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


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0691 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.