Re: Универсальная структура данных
От: flаt  
Дата: 24.02.14 07:32
Оценка: 4 (1)
Здравствуйте, CEMb, Вы писали:

CEM>Всем привет


CEM>Использую MS VC++ 2010.


CEM>Хочется чего-то похожего на динамические классы в JScript, или как они называются?


Посмотрите в сторону JSON и его реализаций. В большинстве случаев у вас будет json::value с подходящими вам свойствами, а в некоторых реализациях есть ещё и "пути": json::value().get(L"root.child[0].prop").

Конечно, backend'ом может быть и XML, но подобных решений под него не видел, кроме boost::property_tree.
Re: Универсальная структура данных
От: Warturtle  
Дата: 24.02.14 15:07
Оценка: 4 (1)
Здравствуйте, CEMb, Вы писали:

CEM>Всем привет


CEM>Использую MS VC++ 2010.


CEM>Хочется чего-то похожего на динамические классы в JScript, или как они называются?


CEM>Хочется сделать свойство:

CEM>
CEM>template<class T> class CProp
CEM>{
CEM>    std::string          m_strName;
CEM>    T                    m_Value;
CEM>    std::vector<CProp*>  m_Props;
CEM>//...
CEM>};
CEM>


CEM>...


CEM>Кроме того, хочется получить быстрый доступ к свойствам, приближенно к obj.Caption.Subcaption, как это в JScript


CEM>Вся эта штука, по идее, удачно укладывается в XML, может быть есть готовые средства (без доп. инсталляции софта и активыксов!), код, которыми можно загрузить в некий объект xml-ку и потом просто дёргать методы, чтобы получать содержимое тегов? Судя по задаче, такое уже должно быть реализовано много раз.


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

CEM>В общем, хочется универсальности, простоты и удобства. Лучше с xml-ем, но можно и без.

Для похожих целей (если я правильно понял задачу) я себе делал такой самокат на базе бустовых fusion+preprocessor+property_tree+typeof(для C++03 или как там его правильно маркировать). Во фьюжене есть аналогичные описываемому ниже MY_DEFINE_PROPERTIES_IMPL макросы, как мне тут однажды указали, но там все равно остается дублирование (либо новый класс объявляется на базе имеющейся сишной структуры, либо нужно отдельно описать тэги), а мне удалось от него полностью избавиться. Пример использования:
struct PropsTraits
{
    static ATL::CPath GetLogPath();
    MY_DEFINE_PROPERTIES_IMPL(
        Storage, 1, 0, MY_DEFINE_PROPERTIES_TUPLED_META,
        ( (LogPath, ("LogFile", GetLogPath())) )
        ( (LogLevel, ("LogLevel", Utils::LogLevel::None)) )
        ( (ICase, ("SearchICase", true)) )
    );
};

struct Props 
    : public PropsTraits
    , public PropsTraits::Storage
{
    void Load();
    void Save();
};
...
// Где-то в галактике
Props props;
props.Load();
ATL::CPath const & logPath = props.At< Props::LogPath >();
props.At< Props::ICase >() = false;

Смысл таков: макрос MY_DEFINE_PROPERTIES_IMPL объявляет список классов-тэгов (LogPath, LogLevel, ICase) с некими "метаданными" (в данном случае это typedef'ы для типов значения и 2 статические функции Name и Default, которые, соотв-но, возвращают рантаймовое имя ("LogFile", "LogLevel",...) и значение по умолчанию для данного свойства (тут это GetLogPath(), Utils::LogLevel::None и true — типы выводятся бустовым TYPEOF)). Реализация Load/Save при этом тривиальная и выглядит примерно так:
void Props::Load()
{
    Utils::RegLoader const loader(HKEY_CURRENT_USER, GetRegSubKeyPath());
    fusion::for_each(*this, loader);
}

void Props::Save()
{
    Utils::RegSaver const saver(HKEY_CURRENT_USER, GetRegSubKeyPath());
    fusion::for_each(*this, saver);
}

Тут данные хранятся в реестре виндовса, для xml нужны аналогичные "лоадер" и "сейвер":
namespace Utils
{
    struct RegHandlerBase
    {
        RegHandlerBase() {}

    protected:
        ATL::CRegKey mutable m_key;
    };

    struct RegSaver : RegHandlerBase
    {
        RegSaver(HKEY const keyParent, LPCTSTR const keyName)
        {
            LONG const keyOpen = m_key.Create(keyParent, keyName);
            MY_CHECK_WIN_ERROR_SUCCESS( keyOpen );
        }
        template< class PairT >
        void operator ()(PairT const & data) const
        {
            SetRegValue(m_key, PairT::first_type::Name(), data.second);
        }
    };

    struct RegLoader : RegHandlerBase
    {
        RegLoader(HKEY const keyParent, LPCTSTR const keyName)
        {
            LONG const keyCreate = m_key.Create(keyParent, keyName);
            MY_CHECK_WIN_ERROR_SUCCESS( keyCreate );
            LONG const keyOpen = m_key.Open(keyParent, keyName, KEY_READ);
            MY_CHECK_WIN_ERROR_SUCCESS( keyOpen );
        }

        template< class PairT >
        void operator ()(PairT & data) const
        {
            data.second = GetRegValue< PairT::second_type >(
                m_key
                , PairT::first_type::Name()
                , PairT::first_type::Default()
            );
        }
    };

} //namespace Utils {

Добавление/удаление новых свойств в PropsTraits::Storage, таким образом, полностью декларативно: нужно только добавить строку с тэгом и "метаданными" и обеспечить наличие соответствующих функций ввода-вывода для данных типов (в этом примере функции GetRegValue/SetRegValue). Если подходит, запощу исходник целиком.
Re[3]: Универсальная структура данных
От: antropolog  
Дата: 24.02.14 20:26
Оценка: +1
Здравствуйте, CEMb, Вы писали:

CEM>Кстати, за что boost ругают?


за то же за что ругают windows, linux, C++, Java, iPhone, ВАЗ и Путина — за то что всем не угодишь.
Re: Универсальная структура данных
От: MasterZiv СССР  
Дата: 26.02.14 13:32
Оценка: -1
On 24.02.2014 10:02, CEMb wrote:

> Хочется чего-то похожего на динамические классы в JScript, или как они

> называются?

Это что-то называется

std::map< std::string, boost::any >
Posted via RSDN NNTP Server 2.1 beta
Универсальная структура данных
От: CEMb  
Дата: 24.02.14 06:02
Оценка:
Всем привет

Использую MS VC++ 2010.

Хочется чего-то похожего на динамические классы в JScript, или как они называются?

Хочется сделать свойство:
template<class T> class CProp
{
    std::string          m_strName;
    T                    m_Value;
    std::vector<CProp*>  m_Props;
//...
};


т.е. дерево свойств.

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

имя      тип     значение
---------------------------
Caption  string  "Something"
Count    INT64   123
Smth1    CSmth   (...)

и так далее

Кроме того, хочется получить быстрый доступ к свойствам, приближенно к obj.Caption.Subcaption, как это в JScript

Вся эта штука, по идее, удачно укладывается в XML, может быть есть готовые средства (без доп. инсталляции софта и активыксов!), код, которыми можно загрузить в некий объект xml-ку и потом просто дёргать методы, чтобы получать содержимое тегов? Судя по задаче, такое уже должно быть реализовано много раз.

Раньше я подобную задачу решал через классы-шаблоны, отнаследованные от интерфейса, указатели на который я и складывал в вектор. Но тут проблема была в том, что интерфейс ничего не знает о типах параметров, значения которых надо было устанавливать-считывать. Частично проблема решалась тем, что шаблоны сами работали с целевым источником-приёмником ресурсов, частично тем, что я работал напрямую с экземплярами этих классов, и частично за счёт некого универсально класса строки, который кастовался во всё подряд, и интерфейс просто устанавливал-возвращал строчное значение. Но это как-то не очень красиво получается
В общем, хочется универсальности, простоты и удобства. Лучше с xml-ем, но можно и без.
Re[2]: Универсальная структура данных
От: CEMb  
Дата: 24.02.14 16:32
Оценка:
Здравствуйте, flаt, Вы писали:

F> кроме boost::property_tree.


О! Вот это прикольная штука, судя по описанию, это почти оно есть Поставил, пробую, пока нравится.
Кстати, за что boost ругают?
Re[2]: Универсальная структура данных
От: CEMb  
Дата: 24.02.14 16:34
Оценка:
Здравствуйте, Warturtle, Вы писали:

W>Если подходит, запощу исходник целиком.


Я сначала попробую использовать чистый boost::property_tree::ptree, если его будет недостаточно, тогда ага
Re: Универсальная структура данных
От: velkin Земля  
Дата: 24.02.14 22:26
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Всем привет


CEM>Использую MS VC++ 2010.


CEM>Хочется чего-то похожего на динамические классы в JScript, или как они называются?


Используй Qt, в его основе лежит метаобъектная система. Между прочим именно это позволяет использовать QtScript, то есть по сути JavaScript. Естественно можно извлекать из объекта доступные свойства, методы, интерфейсы, перечисления, дополнительную информацию и т.д. К сожалению хотя по Qt и есть хорошие книги, от авторов Макс Шлее, Бланшет & Саммерфилд и другие, но это уровень Beginner. Мощнейший механизм для создания динамических архитектур встроенный прямо в QObject обычно остаётся за кадром.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.