Re[6]: SRC: auto_value<>
От: Кодт Россия  
Дата: 12.01.04 11:19
Оценка:
Здравствуйте, MShura, Вы писали:

К>>А если экземпляр — это член другого класса, тогда как быть? Тут не все так просто...

MS>А в чем проблема?Основное условие — все экземпляры/подэкземпляры должны создаваться через new.
MS>Это так сказать цена за удобство.

Тебе не кажется, что каждый int на куче создавать — это дорогая цена?
Кроме того, такая утилитка
template<class T>
class pointer
{
  T* p;
public:
  pointer() : p(new T()) {}
  template<class V> pointer(const V& v) : p(new T(v)) {}
  pointer(const pointer<T>& ptr) : p(new T(*ptr)) {}

  ~pointer() { delete p; }

  T& operator*() { return *p; }
  const T& operator*() const { return *p; }

  T* operator->() { return p; }
  const T* operator->() const { return p; }
};

всегда будет инициализировать данные так как надо (вызывая конструктор без параметров).
И совершенно незачем химичить с new.
Перекуём баги на фичи!
Re[7]: SRC: auto_value<>
От: MShura  
Дата: 12.01.04 12:41
Оценка:
К>Тебе не кажется, что каждый int на куче создавать — это дорогая цена?

Вообще-то твой начальный пост содержал строку:
"Вот, достало ловить ошибки с неинициализованными членами больших классов, вида"

Я сказал, как я поступаю в таком случае. А теперь у тебя от большого класса остался только int?
Re[8]: SRC: auto_value<>
От: Кодт Россия  
Дата: 13.01.04 09:09
Оценка:
Здравствуйте, MShura, Вы писали:

MS>Вообще-то твой начальный пост содержал строку:

MS>"Вот, достало ловить ошибки с неинициализованными членами больших классов, вида"

MS>Я сказал, как я поступаю в таком случае. А теперь у тебя от большого класса остался только int?


Неинициализированные члены большого класса.
class SuperPuper
{
public:
  SuperPuper() : x_(10), y_(20), z_(30), yes_(true), no_(false), cancel_(false) {}
  SuperPuper(int x, int y, int z) : x_(x), y_(y), z_(z), yes_(true), no_(false), cancel_(false) {}
  SuperPuper(int ync) : x_(10), y_(20), z_(30), yes_(ync==0), no_(ync==1), cancel_(ync==2) {}

private:
  int x_;
  int y_;
  int z_;
  bool yes_, no_, cancel_;
  ...
  ...
  ...
  char c_; // добавили в новой версии, в конструкторы прописать забыли.
};

Для большого класса в любом случае существует конструктор, а порой и не один. Так что формально объект этого класса будет проинициализирован (а если нет конструктора без параметров — то компилятор еще и по пальцам надает за забывчивость) при включении его членом другого класса.
А вот для скалярных типов это действительно проблема.



Я еще раз хочу подчеркнуть: изыск возник как реальная потребность при разработке и сопровождении больших проектов.
Перекуём баги на фичи!
Re: SRC: auto_value<>
От: _nn_ www.nemerleweb.com
Дата: 20.04.04 08:34
Оценка:
Здравствуйте, Кодт, Вы писали:

Вот небольшое изменение от меня :
template<typename T>
class ExtractPtr
{
public:
    typedef T Type;
};

template<typename T>
class ExtractPtr<T*>
{
public:
    typedef T Type;
};

template<typename T,T t_init=0,T t_default=t_init>
class AutoValue
{
    T m_t;
public:
    // Constructor
    AutoValue() : m_t(t_init) {}
    template<class T2>
    AutoValue(T2& t) : m_t(t) {}

    // Data
    const T& Data() const { return m_t; }
    T& Data() { return m_t; }

    // Operators
    // T
    operator const T&() const { return m_t; }
    operator T&() { return m_t; }

    // Functor
    T& operator()() { return m_t; }
    const T& operator()() const { return m_t; }

    // Arithmetic
    template<typename T2> const AutoValue& operator=(const T2& t) { m_t=t; return *this; }
    template<typename T2> const AutoValue& operator+=(const T2& t) { m_t+=t; return *this; }
    template<typename T2> const AutoValue& operator-=(const T2& t) { m_t-=t; return *this; }
    template<typename T2> const AutoValue& operator*=(const T2& t) { m_t*=t; return *this; }
    template<typename T2> const AutoValue& operator/=(const T2& t) { m_t/=t; return *this; }
    template<typename T2> const AutoValue& operator%=(const T2& t) { m_t%=t; return *this; }
    template<typename T2> const AutoValue& operator&=(const T2& t) { m_t&=t; return *this; }
    template<typename T2> const AutoValue& operator|=(const T2& t) { m_t|=t; return *this; }
    template<typename T2> const AutoValue& operator^=(const T2& t) { m_t^=t; return *this; }
    template<typename T2> const AutoValue& operator<<=(const T2& t) { m_t<<=t; return *this; }
    template<typename T2> const AutoValue& operator>>=(const T2& t) { m_t>>=t; return *this; }

    // Compare
    template<typename T2> const bool operator==(const T2& t) const { return m_t==t; }
    template<typename T2> const bool operator!=(const T2& t) const { return m_t!=t; }
    template<typename T2> const bool operator>(const T2& t) const { return m_t>t; }
    template<typename T2> const bool operator>=(const T2& t) const { return m_t>=t; }
    template<typename T2> const bool operator<(const T2& t) const { return m_t<t; }
    template<typename T2> const bool operator<=(const T2& t) const { return m_t<=t; }

    // Increment , Decrement
    const AutoValue& operator++() { ++m_t; return *this; }
    const T& operator++(int) { return m_t++; }
    const AutoValue& operator--() { --m_t; return *this; }
    const T& operator--(int) { return m_t--; }

    // Pointers
    T* operator&() { return &m_t; }
    const T* operator&() const { return &m_t; }
    typename ExtractPtr<T>::Type& operator*() { return *m_t; }
    const typename ExtractPtr<T>::Type& operator*() const { return *m_t; }
    typename ExtractPtr<T>::Type& operator->() { return *m_t; }
    const typename ExtractPtr<T>::Type& operator->() const { return *m_t; }

    // Array
    T& operator[](int index) { return m_t[index]; }
    const T& operator[](int index) const { return m_t[index]; }

    // Functions
    void Reset() { m_t=t_default; }
};
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 10.10.04 11:26
Оценка:
Здравствуйте, Кодт, Вы писали:

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



class MyBigClass
{
  auto_value<bool /* , false */ > m_bEnabled;
  limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
  ...

public:
  MyBigClass() {} // все члены инициализируются сами - как сумеют
  ...
  bool isEnabled() { return m_bEnabled; } // получим false, а не 0xCDCDCDCD
  void setEnabled(bool b) { m_bEnabled = b; }
  ...
};


В данном случае номер порта может присваиваться из определенного промежутка, в противном случае получите out_of_range.
Ну и имплементация limit достаточно проста:


template< typename T, size_t min, size_t max>
class limit : public T
{
    public:
    typedef T data_t;
    typedef limit& self_t;

    //default ctor
    inline limit() : T() {}

    // ctor with 1 parameter( including copy constructor)
    template< class V >
    inline limit(V v) : T(v) {}

    //access to data
    inline const T& data() const { return (T&)*this; }
    inline T& data() { return (T&)*this; }

    // means that original type is simple
    operator T () const { return data(); }
    operator const T& () const { return data(); }
    operator T& () { return data(); }

    //assignment operators
    template< class V > inline self_t operator =   (V v) 
    { 
        if( v < min || v > max )
            throw std::out_of_range("new value not in the range");
        data() = v;
        return *this; 
    }
    template< class V > inline self_t operator +=  (V v) 
    {
        T tmp = data();
        tmp +=  v; 
        *this = tmp;
        return *this; 
    }
    template< class V > inline self_t operator -=  (V v) 
    { 
        T tmp = data();
        tmp -=  v; 
        *this = tmp;
        return *this; 
    }
    template< class V > inline self_t operator *=  (V v) 
    { 
        T tmp = data();
        tmp *=  v; 
        *this = tmp;
        return *this; 
    }
    template< class V > inline self_t operator /=  (V v) 
    { 
        T tmp = data();
        tmp /=  v; 
        *this = tmp;
        return *this;
    }
    template< class V > inline self_t operator %=  (V v) 
    { 
        T tmp = data();
        tmp %=  v; 
        *this = tmp;
        return *this;
    }
    template< class V > inline self_t operator &=  (V v) 
    { 
        T tmp = data();
        tmp &=  v; 
        *this = tmp;
        return *this;
    }
    template< class V > inline self_t operator |=  (V v) 
    {     
        T tmp = data();
        tmp |=  v; 
        *this = tmp;
        return *this;
    }
    template< class V > inline self_t operator ^=  (V v) 
    {             
        T tmp = data();
        tmp ^=  v; 
        *this = tmp;
        return *this;
    }
    template< class V > inline self_t operator <<= (V v) 
    {             
        T tmp = data();
        tmp <<=  v; 
        *this = tmp;
        return *this;
    }
    template< class V > inline self_t operator >>= (V v) 
    {             
        T tmp = data();
        tmp >>=  v; 
        *this = tmp;
        return *this;
    }
    //prefix
    inline self_t operator ++ ()    
    { 
        T tmp = data();
        ++tmp;
        *this = tmp;
        return *this;
    }
    //postfix
    inline data_t operator ++ (int) 
    { 
        T tmp = data();
        tmp++; 
        *this = tmp;
        return data();
    }
};



Подобными требованиями-атрибутами можно нагрузить любые члены класса, речь идет не только о лимитах, к примеру можно проверять строку на присвоение пустой строки ( not_empty_string атрибут ), другие требования, которые больше относятся к бизнес логике приложения... Таким образом это завернутое поле запросто может выродиться в полноценное свойство, об отсутствии которых многие сегодня сетуют, тогда значительно упростится кодирование функциональности структур данных, все проверки значений полей сосредоточятся в одних местах.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[2]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 10.10.04 11:38
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>В данном случае номер порта может присваиваться из определенного промежутка, в противном случае получите out_of_range.

B>Ну и имплементация limit достаточно проста:


B>
B>template< typename T, size_t min, size_t max>
B>class limit : public T
B>{
B>


А почему бы не воспользоваться предикатом ?
template<typename T, T t_min, T t_max, typename TPred = std::less<T> >
class limit_t
// : public T - лучше сделать не наследование, а аггрегацию, чтобы была возможность использовать простой тип, IMHO
{
 T t;
public:
 //...
   inline T& data() { return t; }

   template< class V > inline self_t operator =   (V v) 
    { 
        if( TPed(v, t_min)
            throw std::out_of_range("new value not in the range - less than minimum");
        if( TPred(t_max, v)
            throw std::out_of_range("new value not in the range - more than maximum");
        
        data() = v;
        return *this; 
    }
};
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 10.10.04 11:53
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, Batiskaf, Вы писали:


B>>В данном случае номер порта может присваиваться из определенного промежутка, в противном случае получите out_of_range.

B>>Ну и имплементация limit достаточно проста:


B>>
B>>template< typename T, size_t min, size_t max>
B>>class limit : public T
B>>{
B>>


__>А почему бы не воспользоваться предикатом ?

__>
__>template<typename T, T t_min, T t_max, typename TPred = std::less<T> >
__>class limit_t
__>// : public T - лучше сделать не наследование, а аггрегацию, чтобы была возможность использовать простой тип, IMHO
__>{
__> T t;
__>public:
__> //...
__>   inline T& data() { return t; }

__>   template< class V > inline self_t operator =   (V v) 
__>    { 
__>        if( TPred(v, t_min)
__>            throw std::out_of_range("new value not in the range - less than minimum");
__>        if( TPred(t_max, v)
__>            throw std::out_of_range("new value not in the range - more than maximum");
        
__>        data() = v;
__>        return *this; 
__>    }
__>};
__>


для простых типов должна использоваться насадка auto_value, так что не вижу никаких препятствий для наследования. Что же касается параметризирования, то как сказано выше, атрибуты могут вкладываться один в другой, и тогда проблематично будет с этим:

limit_t<auto_value<int, 200>, 200, 100000> a;


лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[4]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 10.10.04 19:23
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, Batiskaf, Вы писали:


B>>>В данном случае номер порта может присваиваться из определенного промежутка, в противном случае получите out_of_range.

B>>>Ну и имплементация limit достаточно проста:


B>>>
B>>>template< typename T, size_t min, size_t max>
B>>>class limit : public T
B>>>{
B>>>


__>>А почему бы не воспользоваться предикатом ?

__>>
__>>template<typename T, T t_min, T t_max, typename TPred = std::less<T> >
__>>class limit_t
__>>// : public T - лучше сделать не наследование, а аггрегацию, чтобы была возможность использовать простой тип, IMHO
__>>{
__>> T t;
__>>public:
__>> //...
__>>   inline T& data() { return t; }

__>>   template< class V > inline self_t operator =   (V v) 
__>>    { 
__>>        if( TPred(v, t_min)
__>>            throw std::out_of_range("new value not in the range - less than minimum");
__>>        if( TPred(t_max, v)
__>>            throw std::out_of_range("new value not in the range - more than maximum");
        
__>>        data() = v;
__>>        return *this; 
__>>    }
__>>};
__>>


B>для простых типов должна использоваться насадка auto_value, так что не вижу никаких препятствий для наследования. Что же касается параметризирования, то как сказано выше, атрибуты могут вкладываться один в другой, и тогда проблематично будет с этим:


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

B>
B>limit_t<auto_value<int, 200>, 200, 100000> a;
B>


B>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

Здесь вы говорите обратное от того что сказано вами выше
А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки

P.S.
В вашем коде есть небольшой недочет, а имено :
limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;

Что будет если не выбрать не 5000, а 4999 ?
Ничего

Так что нужна проверка для этого.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[5]: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 10.10.04 21:19
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, Batiskaf, Вы писали:


B>>Здравствуйте, _nn_, Вы писали:


__>>>Здравствуйте, Batiskaf, Вы писали:


B>>>>В данном случае номер порта может присваиваться из определенного промежутка, в противном случае получите out_of_range.

B>>>>Ну и имплементация limit достаточно проста:


B>>>>
B>>>>template< typename T, size_t min, size_t max>
B>>>>class limit : public T
B>>>>{
B>>>>


__>>>А почему бы не воспользоваться предикатом ?

__>>>
__>>>template<typename T, T t_min, T t_max, typename TPred = std::less<T> >
__>>>class limit_t
__>>>// : public T - лучше сделать не наследование, а аггрегацию, чтобы была возможность использовать простой тип, IMHO
__>>>{
__>>> T t;
__>>>public:
__>>> //...
__>>>   inline T& data() { return t; }

__>>>   template< class V > inline self_t operator =   (V v) 
__>>>    { 
__>>>        if( TPred(v, t_min)
__>>>            throw std::out_of_range("new value not in the range - less than minimum");
__>>>        if( TPred(t_max, v)
__>>>            throw std::out_of_range("new value not in the range - more than maximum");
        
__>>>        data() = v;
__>>>        return *this; 
__>>>    }
__>>>};
__>>>


B>>для простых типов должна использоваться насадка auto_value, так что не вижу никаких препятствий для наследования. Что же касается параметризирования, то как сказано выше, атрибуты могут вкладываться один в другой, и тогда проблематично будет с этим:


__>Наверное в большинстве случаев будут использоваться простые типы, а так для них придется еще использовать дополнительный класс.

__>А вообще можно сделать два класса, с наследованием и без

B>>
B>>limit_t<auto_value<int, 200>, 200, 100000> a;
B>>


B>>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

__>Здесь вы говорите обратное от того что сказано вами выше
Ну имелось в виду простые интегральные типы, обернутые в auto_value, смысл от этого не меняется.

__>А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки


для этих целей я использую not_empty_string атрибут, просто не представляю ситуацию, когда нужна строка длинной не меньше 2 символов и не больше 9 к примеру...

__>P.S.

__>В вашем коде есть небольшой недочет, а имено :
__>
__>limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
__>

__>Что будет если не выбрать не 5000, а 4999 ?
__>Ничего

__>Так что нужна проверка для этого.


Я не решился в конструкторе выбрасывать исключение, да и преследовалась цель защитить бизнес логику приложения от глупого пользователся, а не от глупого программиста, который делает явную ошибку в одной строке.
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[6]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 10.10.04 21:42
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>>>
B>>>limit_t<auto_value<int, 200>, 200, 100000> a;
B>>>


B>>>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

__>>Здесь вы говорите обратное от того что сказано вами выше
B>Ну имелось в виду простые интегральные типы, обернутые в auto_value, смысл от этого не меняется.

__>>А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки


B>для этих целей я использую not_empty_string атрибут, просто не представляю ситуацию, когда нужна строка длинной не меньше 2 символов и не больше 9 к примеру...

Например для представления числа от 0 до 100, и есть задача чтобы все 3 цифры были, т.е. 001, 002...

__>>P.S.

__>>В вашем коде есть небольшой недочет, а имено :
__>>
__>>limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
__>>

__>>Что будет если не выбрать не 5000, а 4999 ?
__>>Ничего

__>>Так что нужна проверка для этого.


B>Я не решился в конструкторе выбрасывать исключение, да и преследовалась цель защитить бизнес логику приложения от глупого пользователся, а не от глупого программиста, который делает явную ошибку в одной строке.

А если будет такая ситуация то будет плохо, все же надо как-нибудь придумать защиту.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[7]: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 11.10.04 09:16
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, Batiskaf, Вы писали:


B>>>>
B>>>>limit_t<auto_value<int, 200>, 200, 100000> a;
B>>>>


B>>>>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

__>>>Здесь вы говорите обратное от того что сказано вами выше
B>>Ну имелось в виду простые интегральные типы, обернутые в auto_value, смысл от этого не меняется.

__>>>А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки


B>>для этих целей я использую not_empty_string атрибут, просто не представляю ситуацию, когда нужна строка длинной не меньше 2 символов и не больше 9 к примеру...

__>Например для представления числа от 0 до 100, и есть задача чтобы все 3 цифры были, т.е. 001, 002...
Ну это вряд ли, форматирование строки для представления даты скорее бы подошло, но это уже не лимит.

__>>>P.S.

__>>>В вашем коде есть небольшой недочет, а имено :
__>>>
__>>>limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
__>>>

__>>>Что будет если не выбрать не 5000, а 4999 ?
__>>>Ничего

__>>>Так что нужна проверка для этого.


B>>Я не решился в конструкторе выбрасывать исключение, да и преследовалась цель защитить бизнес логику приложения от глупого пользователся, а не от глупого программиста, который делает явную ошибку в одной строке.

__>А если будет такая ситуация то будет плохо, все же надо как-нибудь придумать защиту.

Да запросто:

в класс auto_value добавить в паблик следующую строку:


enum {def_value = i}; // где i это шаблонный параметр значения по умолчанию


в класс limit добавить следующее:


#include <boost/static_assert.hpp>

    BOOST_STATIC_ASSERT( min <= T::def_value );
    BOOST_STATIC_ASSERT( max >= T::def_value );
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[8]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 11.10.04 12:15
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, Batiskaf, Вы писали:


B>>>>>
B>>>>>limit_t<auto_value<int, 200>, 200, 100000> a;
B>>>>>


B>>>>>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

__>>>>Здесь вы говорите обратное от того что сказано вами выше
B>>>Ну имелось в виду простые интегральные типы, обернутые в auto_value, смысл от этого не меняется.

__>>>>А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки


B>>>для этих целей я использую not_empty_string атрибут, просто не представляю ситуацию, когда нужна строка длинной не меньше 2 символов и не больше 9 к примеру...

__>>Например для представления числа от 0 до 100, и есть задача чтобы все 3 цифры были, т.е. 001, 002...
B>Ну это вряд ли, форматирование строки для представления даты скорее бы подошло, но это уже не лимит.
Ну можно придумать использования разные и не только со строкой, получится универсальный класс для многих вещей, а то так нужен еще один класс будет для реализации какой-нибудь дополнительной идеи.

__>>>>P.S.

__>>>>В вашем коде есть небольшой недочет, а имено :
__>>>>
__>>>>limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
__>>>>

__>>>>Что будет если не выбрать не 5000, а 4999 ?
__>>>>Ничего

__>>>>Так что нужна проверка для этого.


B>>>Я не решился в конструкторе выбрасывать исключение, да и преследовалась цель защитить бизнес логику приложения от глупого пользователся, а не от глупого программиста, который делает явную ошибку в одной строке.

__>>А если будет такая ситуация то будет плохо, все же надо как-нибудь придумать защиту.

B>Да запросто:


B>в класс auto_value добавить в паблик следующую строку:



B>
B>enum {def_value = i}; // где i это шаблонный параметр значения по умолчанию
B>


B>в класс limit добавить следующее:



B>
B>#include <boost/static_assert.hpp>

B>    BOOST_STATIC_ASSERT( min <= T::def_value );
B>    BOOST_STATIC_ASSERT( max >= T::def_value );
B>


А если использовать тип где enum не помогает, например float, будет проблема.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[9]: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 11.10.04 12:48
Оценка:
Здравствуйте, _nn_, Вы писали:

__>Здравствуйте, Batiskaf, Вы писали:


B>>Здравствуйте, _nn_, Вы писали:


__>>>Здравствуйте, Batiskaf, Вы писали:


B>>>>>>
B>>>>>>limit_t<auto_value<int, 200>, 200, 100000> a;
B>>>>>>


B>>>>>>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

__>>>>>Здесь вы говорите обратное от того что сказано вами выше
B>>>>Ну имелось в виду простые интегральные типы, обернутые в auto_value, смысл от этого не меняется.

__>>>>>А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки


B>>>>для этих целей я использую not_empty_string атрибут, просто не представляю ситуацию, когда нужна строка длинной не меньше 2 символов и не больше 9 к примеру...

__>>>Например для представления числа от 0 до 100, и есть задача чтобы все 3 цифры были, т.е. 001, 002...
B>>Ну это вряд ли, форматирование строки для представления даты скорее бы подошло, но это уже не лимит.
__>Ну можно придумать использования разные и не только со строкой, получится универсальный класс для многих вещей, а то так нужен еще один класс будет для реализации какой-нибудь дополнительной идеи.
Дык как я погляжу не очень получается придумать, второй день уже придумываем

__>>>>>P.S.

__>>>>>В вашем коде есть небольшой недочет, а имено :
__>>>>>
__>>>>>limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
__>>>>>

__>>>>>Что будет если не выбрать не 5000, а 4999 ?
__>>>>>Ничего

__>>>>>Так что нужна проверка для этого.


B>>>>Я не решился в конструкторе выбрасывать исключение, да и преследовалась цель защитить бизнес логику приложения от глупого пользователся, а не от глупого программиста, который делает явную ошибку в одной строке.

__>>>А если будет такая ситуация то будет плохо, все же надо как-нибудь придумать защиту.

B>>Да запросто:


B>>в класс auto_value добавить в паблик следующую строку:



B>>
B>>enum {def_value = i}; // где i это шаблонный параметр значения по умолчанию
B>>


B>>в класс limit добавить следующее:



B>>
B>>#include <boost/static_assert.hpp>

B>>    BOOST_STATIC_ASSERT( min <= T::def_value );
B>>    BOOST_STATIC_ASSERT( max >= T::def_value );
B>>


__>А если использовать тип где enum не помогает, например float, будет проблема.


Ну ты нудник!

const static T  def_value = i;// где i это шаблонный параметр значения по умолчанию


Кстати, хорошо что вспомнил, на VC7 второй темплейт параметр с float не проходит, The C++ standard does not allow floating point non-type template parameters. К барьеру, мистер Кодт!
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[10]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 11.10.04 13:14
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>Здравствуйте, _nn_, Вы писали:


__>>Здравствуйте, Batiskaf, Вы писали:


B>>>Здравствуйте, _nn_, Вы писали:


__>>>>Здравствуйте, Batiskaf, Вы писали:


B>>>>>>>
B>>>>>>>limit_t<auto_value<int, 200>, 200, 100000> a;
B>>>>>>>


B>>>>>>>лимит имеет смысл заводить для интегральных величин (какой смысл у limit_t<std::string> к примеру), так что операторов "больше/меньше" вполне достаточно.

__>>>>>>Здесь вы говорите обратное от того что сказано вами выше
B>>>>>Ну имелось в виду простые интегральные типы, обернутые в auto_value, смысл от этого не меняется.

__>>>>>>А вообще в любом дополнительная функциональность не помешает, кроме того смысл для limit_t<std::string> можно придумать, например для ограничения длины строки


B>>>>>для этих целей я использую not_empty_string атрибут, просто не представляю ситуацию, когда нужна строка длинной не меньше 2 символов и не больше 9 к примеру...

__>>>>Например для представления числа от 0 до 100, и есть задача чтобы все 3 цифры были, т.е. 001, 002...
B>>>Ну это вряд ли, форматирование строки для представления даты скорее бы подошло, но это уже не лимит.
__>>Ну можно придумать использования разные и не только со строкой, получится универсальный класс для многих вещей, а то так нужен еще один класс будет для реализации какой-нибудь дополнительной идеи.
B>Дык как я погляжу не очень получается придумать, второй день уже придумываем
Если долго мучаться что-нибудь получится %)

__>>>>>>P.S.

__>>>>>>В вашем коде есть небольшой недочет, а имено :
__>>>>>>
__>>>>>>limit<auto_value<unsigned short, 5000 > 5000, 25000> m_PortNumber;
__>>>>>>

__>>>>>>Что будет если не выбрать не 5000, а 4999 ?
__>>>>>>Ничего

__>>>>>>Так что нужна проверка для этого.


B>>>>>Я не решился в конструкторе выбрасывать исключение, да и преследовалась цель защитить бизнес логику приложения от глупого пользователся, а не от глупого программиста, который делает явную ошибку в одной строке.

__>>>>А если будет такая ситуация то будет плохо, все же надо как-нибудь придумать защиту.

B>>>Да запросто:


B>>>в класс auto_value добавить в паблик следующую строку:



B>>>
B>>>enum {def_value = i}; // где i это шаблонный параметр значения по умолчанию
B>>>


B>>>в класс limit добавить следующее:



B>>>
B>>>#include <boost/static_assert.hpp>

B>>>    BOOST_STATIC_ASSERT( min <= T::def_value );
B>>>    BOOST_STATIC_ASSERT( max >= T::def_value );
B>>>


__>>А если использовать тип где enum не помогает, например float, будет проблема.


B>Ну ты нудник!


B>
B>const static T  def_value = i;// где i это шаблонный параметр значения по умолчанию
B>

Не вижу что с T=float будет работать это

B>Кстати, хорошо что вспомнил, на VC7 второй темплейт параметр с float не проходит, The C++ standard does not allow floating point non-type template parameters. К барьеру, мистер Кодт!


Можно попробовать так : (извращение)
template<typename T, T t_value>
struct value_wrapper
{
 inline static T& data()
 {
  static T value=t_value;
  return value;
 }

 template<typename T2, T2 t_value2> 
 bool operator<(const value_wrapper<T2,t_value2>& r) const
 { return data()<r.data(); }
};

/*
Вариант №2 - Тогда не нужен вызов функции 

template<typename T, T t_value>
struct value_wrapper
{
 inline static T& data()
 { return value; }

 template<typename T2, T2 t_value2> 
 bool operator<(const value_wrapper<T2,t_value2>& r) const
 { return data()<r.data(); }
private:
 static const T value;
};

template<typename T, T t_value>
const T value_wrapper<T,t_value>::value = t_value;
*/

template<
        typename T,
        typename TMin = value_wrapper<T,T()>,
        typename TMax = value_wrapper<T,~T()>,
        typename TLess = std::less<T> >
class limit_t
{
public:
 T& data() { return static_cast<T&>(*this); }
 const T& data() const { return static_cast<const T&>(*this); }
 
 template<typename T2>
 limit_t& operator=(const limit_t<T2>& r)
 {
  if(TLess(data(),TMin::data())
   throw std::out_of_range("less than minimum");
  if(TLess(TMax::data(),data())
   throw std::out_of_range("more than maximum);
 //...
 }
};

template<
        typename T,
        T t_min,
        T t_max,
        typename TLess = std::less<T> >
class limit_t_pod : public limit_t<T,value_wrapper<T,t_min>,value_wrapper<T,t_max>,TLess>
{
//...
};


limit_t<int, value_wrapper<int,10>, value_wrapper<int,20> > limit_int_10_to_20;
limit_t_pod<int, 10, 20 > limit_pod_int_10_to_20;
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[11]: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 11.10.04 16:08
Оценка:
Здравствуйте, _nn_, Вы писали:


__>>>>>А если будет такая ситуация то будет плохо, все же надо как-нибудь придумать защиту.


B>>>>Да запросто:


B>>>>в класс auto_value добавить в паблик следующую строку:



B>>>>
B>>>>enum {def_value = i}; // где i это шаблонный параметр значения по умолчанию
B>>>>


B>>>>в класс limit добавить следующее:



B>>>>
B>>>>#include <boost/static_assert.hpp>

B>>>>    BOOST_STATIC_ASSERT( min <= T::def_value );
B>>>>    BOOST_STATIC_ASSERT( max >= T::def_value );
B>>>>


__>>>А если использовать тип где enum не помогает, например float, будет проблема.


B>>Ну ты нудник!


B>>
B>>const static T  def_value = i;// где i это шаблонный параметр значения по умолчанию
B>>

__>Не вижу что с T=float будет работать это

B>>Кстати, хорошо что вспомнил, на VC7 второй темплейт параметр с float не проходит, The C++ standard does not allow floating point non-type template parameters. К барьеру, мистер Кодт!


__>Можно попробовать так : (извращение)

__>[c]
__>template<typename T, T t_value>
__>struct value_wrapper
__>{
__> inline static T& data()
__> {
__> static T value=t_value;
__> return value;
__> }

__> template<typename T2, T2 t_value2>

__> bool operator<(const value_wrapper<T2,t_value2>& r) const
__> { return data()<r.data(); }
__>};

Ха, проблема не только в том что статическая константа только интегрального типа может быть инициализирована в объявлении класса, вещественным числом даже запараметризировать темплейт нельзя, вот попробуй свой код:


typedef   value_wrapper< float, 10.1>  float_value_wrapper;


для float нужно свою специализацию auto_value ваять, что я и сказал Кодту.

Для меня же интересно несколько другое применение таких атрибутов, что бы в рантайме можно было собрать всю цепочку атрибутов, проитерировать, повызывать каждый по отдельности. Вот к примеру есть строковое поле, в которое вводится IID объекта, на него можно навесить один атрибут, контролирующий длину строки ( не менее 36 символов ) и валидность этого IID для текущей системы, типа как то так:


struct length_t : public T
{
...
    template< class V > inline self_t operator =   (V v) 
    { 
        if( v.length() != size )
            throw std::length_error("string is too big");
        data() = v;
        return *this; 
    }
...
};

template< typename T>
struct validate_iid_t : public T
{
...
    validate_iid_t () : T()
    {
      data()=default_iid;
    }
    template< class V > inline self_t operator =   (V v) 
    { 
        if( !IsValidIID(v) )
            throw std::invalid_iid_error("bla bla");
        data() = v;
        return *this; 
    }
...
};


И тогда поле класса:

length_t <valid_iid_t<std::string>, 36 > _ObjectID;


и хотелось бы использовать эти атрибуты в рантайме динамически, например каждый атрибут будет имплементировать несколько виртуальных функций, Next ( для навигации и перехода к следующему атрибуту ), возможность посетить атрибут, много крутых полезных вещей можно из этого поиметь...
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[12]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 11.10.04 16:38
Оценка:
Здравствуйте, Batiskaf, Вы писали:

__>>Можно попробовать так : (извращение)

__>>
__>>template<typename T, T t_value>
__>>struct value_wrapper
__>>{
__>> inline static T& data()
__>> {
__>>  static T value=t_value;
__>>  return value;
__>> }

__>> template<typename T2, T2 t_value2> 
__>> bool operator<(const value_wrapper<T2,t_value2>& r) const
__>> { return data()<r.data(); }
__>>};

B>Ха, проблема не только в том что статическая константа только интегрального типа может быть инициализирована в объявлении класса, вещественным числом даже запараметризировать темплейт нельзя, вот попробуй свой код:

B>
B>typedef   value_wrapper< float, 10.1>  float_value_wrapper;
B>

Зато можно так
struct min_my_float
{
 static float data()
 {
  static const float value=10.1f;
  return value;
 }
};

struct max_my_float
{
 static float data()
 {
  static const float value=100.2f;
  return value;
 }
};

limit_t<float, min_my_float, max_my_float> x;


B>для float нужно свою специализацию auto_value ваять, что я и сказал Кодту.


B>Для меня же интересно несколько другое применение таких атрибутов, что бы в рантайме можно было собрать всю цепочку атрибутов, проитерировать, повызывать каждый по отдельности. Вот к примеру есть строковое поле, в которое вводится IID объекта, на него можно навесить один атрибут, контролирующий длину строки ( не менее 36 символов ) и валидность этого IID для текущей системы, типа как то так:



B>
B>struct length_t : public T
B>{
B>...
B>    template< class V > inline self_t operator =   (V v) 
B>    { 
B>        if( v.length() != size )
B>            throw std::length_error("string is too big");
B>        data() = v;
B>        return *this; 
B>    }
B>...
B>};

B>template< typename T>
B>struct validate_iid_t : public T
B>{
B>...
B>    validate_iid_t () : T()
B>    {
B>      data()=default_iid;
B>    }
B>    template< class V > inline self_t operator =   (V v) 
B>    { 
B>        if( !IsValidIID(v) )
B>            throw std::invalid_iid_error("bla bla");
B>        data() = v;
B>        return *this; 
B>    }
B>...
B>};

B>


B>И тогда поле класса:


B>
B>length_t <valid_iid_t<std::string>, 36 > _ObjectID;
B>


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


Что-то я не понял вашу идею.
Можно как-нибудь более подробно ?
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[13]: Навеяно auto_value<> ™ ( от Кодт )
От: Batiskaf Израиль http://www.mult.ru/
Дата: 11.10.04 17:15
Оценка:
Здравствуйте, _nn_, Вы писали:


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


__>Что-то я не понял вашу идею.

__>Можно как-нибудь более подробно ?

Да это мысли в слух, вот тут http://www.rsdn.ru/Forum/Message.aspx?mid=775603
Автор: Batiskaf
Дата: 23.08.04
над одной идеей раздумываю, так вот идея в рантайме эти самые атрибуты обходить с тем что бы при автоматической генерации визуального интерфейса проинтерпретировать атрибуты во фронт сайт, тем самым схемы валидации можно указывать только один раз на уровне структуры данных, а при переносе структуры в другой базис (ведь диалог отображающий содержимое структуры Person это все тот же Person, та же модель, только выраженная другими элементами ) по возможности переносить и схему валидации. Надеюсь что выразился понятно...
Will I live tomorrow? Well I just can't say
But I know for sure — I don't live today.
Jimi Hendrix.
Re[14]: Навеяно auto_value<> ™ ( от Кодт )
От: _nn_ www.nemerleweb.com
Дата: 12.10.04 11:43
Оценка:
Здравствуйте, Batiskaf, Вы писали:

B>Здравствуйте, _nn_, Вы писали:



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


__>>Что-то я не понял вашу идею.

__>>Можно как-нибудь более подробно ?

B>Да это мысли в слух, вот тут http://www.rsdn.ru/Forum/Message.aspx?mid=775603
Автор: Batiskaf
Дата: 23.08.04
над одной идеей раздумываю, так вот идея в рантайме эти самые атрибуты обходить с тем что бы при автоматической генерации визуального интерфейса проинтерпретировать атрибуты во фронт сайт, тем самым схемы валидации можно указывать только один раз на уровне структуры данных, а при переносе структуры в другой базис (ведь диалог отображающий содержимое структуры Person это все тот же Person, та же модель, только выраженная другими элементами ) по возможности переносить и схему валидации. Надеюсь что выразился понятно...

Мы уже отошли от темы auto_value и от limit

Идею я понял, надеюсь
Вот только не представляю реализацию, и до сих пор не понял ваш код в предыдущем посте.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[2]: Навеяно auto_value<> ™ ( от Кодт )
От: Аноним  
Дата: 13.03.05 10:02
Оценка:
up
Re[15]: Навеяно auto_value<> ™ ( от Кодт )
От: Аноним  
Дата: 13.03.05 10:06
Оценка:
up
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.