"Динимаческий" enum
От: Sheridan Россия  
Дата: 29.08.09 11:35
Оценка:
Приветствую!
В силу необходимости храню данные в map<string,string>, так как не знаю заранее, какой ключ будет, так как ключи создаются дефайнами.
Типа такого:
#define AAA(_name) CType *_name = new CType(#_name);
И в последствии #_name попадает в мап в качестве ключа.
Хочется избавиться от строк в качестве ключа, подскажите как извернуться?
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re: "Динимаческий" enum
От: Sashaka Россия  
Дата: 29.08.09 14:51
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Приветствую!

S>В силу необходимости храню данные в map<string,string>, так как не знаю заранее, какой ключ будет, так как ключи создаются дефайнами.
S>Типа такого:
S>#define AAA(_name) CType *_name = new CType(#_name);
S>И в последствии #_name попадает в мап в качестве ключа.
S>Хочется избавиться от строк в качестве ключа, подскажите как извернуться?

можно хеш/контрольную сумму вместо строк использовать?
Re: "Динимаческий" enum
От: Faust Россия  
Дата: 29.08.09 15:57
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Приветствую!

S>В силу необходимости храню данные в map<string,string>, так как не знаю заранее, какой ключ будет, так как ключи создаются дефайнами.
S>Типа такого:
S>#define AAA(_name) CType *_name = new CType(#_name);
S>И в последствии #_name попадает в мап в качестве ключа.
S>Хочется избавиться от строк в качестве ключа, подскажите как извернуться?
#include <map>
#include <string>

template <typename T>
struct def_value
{ static T                    Value; };
template<typename T>
T                    def_value<T>::Value;

template <typename KeyType, typename GUIDType>
GUIDType            GenGUID(const KeyType& key);
template <>
unsigned __int64    GenGUID<std::string, unsigned __int64>(const std::string& key)
{
    // возвращаем уникальное значение, можно через hash-функцию
    return 0;
}

template <typename KeyType, typename GUIDType = unsigned __int64>
class id_generator
{
    typedef KeyType                            key_type;
    typedef GUIDType                        guid_type;
    typedef std::pair<key_type, guid_type>    key_pair;
    typedef std::map<key_type, guid_type>    key_map;
    typedef typename key_map::iterator        key_it;
    key_map                m_mapKeys;
public:
    id_generator(void)
    { }

    const guid_type&    GenGUID(const key_type& key)
    {
        key_it                pFind                = m_mapKeys.find(key);
        if(pFind != m_mapKeys.begin())
        {
            typedef std::pair<key_it, bool>            ib_pair;
            ib_pair                pairIB            =
                m_mapKeys.insert(key_pair(key, ::GenGUID<key_type, guid_type>(key)));
            if(!pairIB.second)
                return def_value<guid_type>::Value;
            pFind                = pairIB.first;
        }
        return pFind->second;
    }
};

int                    _tmain(int argc, _TCHAR* argv[])
{
    id_generator<std::string>        IDGen;
    IDGen.GenGUID("123");
    return 0;
}
Мой компьютер прогоняет бесконечный цикл за 9 секунд, но, мне кажется, он мог бы сделать это быстрее...
Re[2]: "Динимаческий" enum
От: Sheridan Россия  
Дата: 29.08.09 17:37
Оценка:
Приветствую, Sashaka, вы писали:

S> можно хеш/контрольную сумму вместо строк использовать?

Главное стобы потом читабельно было. Потом из мапа уже я достаю string а=amap["mystring"], а хотелось бы string a=amap[mystring]
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re[2]: "Динимаческий" enum
От: Sheridan Россия  
Дата: 29.08.09 17:37
Оценка:
Честно говоря мало чего понял...
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re: "Динимаческий" enum
От: Alexander G Украина  
Дата: 29.08.09 18:15
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Приветствую!

S>В силу необходимости храню данные в map<string,string>, так как не знаю заранее, какой ключ будет, так как ключи создаются дефайнами.
S>Типа такого:
S>#define AAA(_name) CType *_name = new CType(#_name);
S>И в последствии #_name попадает в мап в качестве ключа.
S>Хочется избавиться от строк в качестве ключа, подскажите как извернуться?

Мало что понял. Как присваиваются и читаются значения, где пишется AAA(_name) ?
Русский военный корабль идёт ко дну!
Re[3]: "Динимаческий" enum
От: Faust Россия  
Дата: 29.08.09 18:29
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Честно говоря мало чего понял...

вместо Вашего map<string, string> я предлагаю использовать map<unsigned __int64, string> при помощи id_generator<string, unsigned __int64>. т.е.:
template <typename KeyType, typename GUIDType>
GUIDType        GenGUID(const KeyType& key);
template <>
unsigned __int64    GenGUID<std::string, unsigned __int64>(const std::string& key)
{
    // самый простой вариант реализации
    unsigned __int64    iu64GUID    = 1;
    std::string::iterator    pCursor        = key.begin();
    std::string::iterator    pEnd        = key.end();
    if(pCursor != pEnd)
    do { iu64GUID *= *pCursor; } while(++pCursor != pEnd);
    return iu64GUID;
}

id_generator<string, unsigned __int64>    g_IDGen;

struct your_class
{
    map<unsigned __int64, string>    m_map;
    bool                Insert(const string& szKey, const string& szValue)
    { return m_map.insert(pair<unsigned __int64, string>(g_IDGen.GenGUID(szKey), szValue)).second; }
};

int                    _tmain(int argc, _TCHAR* argv[])
{
    your_class    Obj;
    Obj.Insert("ключевая_строка_1q2w3e4r5t6y7u8i9o0p", "строка_с_данными");
    return 0;
}
но все это имеет смысл лишь только в том случае, когда у Вас your_class::m_map содержит достаточно большое количество элементов и Вам необходимо часто копировать один объект типа your_class в другой.
Мой компьютер прогоняет бесконечный цикл за 9 секунд, но, мне кажется, он мог бы сделать это быстрее...
Немного подробнее
От: Sheridan Россия  
Дата: 29.08.09 18:35
Оценка:
Тут идет объявление имен, к примеру
SELECT(get_forumgroups);
     ALL_FIELDS(get_forumgroups);
FROM(get_forumgroups, forumgroups);

А вот тут — использование:
forumGroups = CLIENT_DB->query("get_forumgroups");

Хочется, чтобы в последнем случае было
forumGroups = CLIENT_DB->query(get_forumgroups);
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re[4]: "Динимаческий" enum
От: Sheridan Россия  
Дата: 29.08.09 18:39
Оценка:
Приветствую, Faust, вы писали:

Насколько я понимаю — мне такое не подходит. Мне нужно чтото именованное. Посмотри пожалуйста этот
Автор: Sheridan
Дата: 29.08.09
пост.
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re[2]: "Динимаческий" enum
От: Sheridan Россия  
Дата: 29.08.09 18:39
Оценка:
Приветствую, Alexander G, вы писали:

AG> Мало что понял. Как присваиваются и читаются значения, где пишется AAA(_name) ?


Написал подробнее
Автор: Sheridan
Дата: 29.08.09
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re: "Динимаческий" enum
От: Erop Россия  
Дата: 29.08.09 20:38
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>И в последствии #_name попадает в мап в качестве ключа.

S>Хочется избавиться от строк в качестве ключа, подскажите как извернуться?

Я так понял, что тебе хочется заводить C++ id в макросах, а потом иметь возможность использовать эти id в качестве ключей? При этом аллокируемые из макроса CType должны знать свои id?

Не ясно тут ещё вот что. в каком пространстве имён должны заводиться эти id?

Один из путей, например, таков:
enum MyID { MyID_0, MyID_MAX = INT_MAX };
class CTypeManager {
public:
    static MyID NewID()
    {
         MyID newId = allocId();
         findOrAllocCType( newId );
         return newId;
    }
    static CType& Get( MyID id ) 
    {
         assert( 0 <= id && id < seed );
         return findOrAllocCType( id );
    }
private:
    static int seed; // == 0
    static MyID allocId()
    {
         return static_cast<MyID>( seed++ );
    } 
    static CType& findOrAllocCType( MyID id )
    {
        static std::vector<CType> data;
        while( id >= data.Size() ) {
            data.push_back( CType( static_cast<MyID>( data.size() ) ) );
        }
        assert( data[id].GetID() == id );
        return data[id];
    }
};

#define AAA(_name) const MyID = CTypeManager::NewID();


Дальше, для доступа к CType всегда используем CTypeManager::Get( id );

Второй путь -- заводить в AAA каждый раз новую структуру, например, и инстанцировать параметризированный этой структурой шаблон. Что-то типа
inline int allocId() { static int i = 0; return i++; }

template<typename TSeed>
struct CTypeIdHolder {
    CTypeIdHolder( const char* ) : //... тут запоминаем строчки, вычисляем что там нам надо, прихраниваем
    static const int Id;
};
template<typename TSeed>
const int CTypeIdHolder<TSeed>::Id = allocId();

#define AAA(NAME) struct NAME; CTypeIdHolder<struct NAME> NAME( #NAME );


Ну и всегда теперь можем написать код, который по имени структуры получает id и лезет в map. Правда при таком подходе нельзя иметь переменную, содержащую имя ключа...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[2]: "Динимаческий" enum
От: Sheridan Россия  
Дата: 29.08.09 21:18
Оценка:
Ммм... А будет ли это быстрее работать, нечели поиск по строковому ключу мапа?
avalon 1.0rc2 rev 300, zlib 1.2.3
build date: 19.08.2009 14:13:36 MSD +04:00
Qt 4.5.2
Matrix has you...
Re[3]: "Динимаческий" enum
От: Erop Россия  
Дата: 29.08.09 21:44
Оценка:
Здравствуйте, Sheridan, Вы писали:

S>Ммм... А будет ли это быстрее работать, нечели поиск по строковому ключу мапа?


Что "это"? Индексирование массива или поиск по ключу? Наверняка да...
Впрочем я не до конца понимаю твою задачу, так что на самом деле
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.