I program c++ and currently have free time, so if anybody needs any coding done, please let me know and I might be able to help!
I program c++ and currently have free time, so if anybody needs any coding done, please let me know and I might be able to help!
simple exercise for you then....
make a host class template that takes 1 policy class as its template parameter. The idea of this class is to hold a value ( normally an integer of some description) and check using the policy that the value is within a prescribed range or throw exception. Min and max have to be queryable. Also this class must be assignable and have an implicit comversion to the policies Type type.
The policy class takes 4 template parameters. The type, min,max and exception to be thrown on min/max violation.
See how you get on with that 1. I expect it to take 10mins to 45 mins depending on how used to templates and policy classes you are.
If you attempt this ill post a solution tomorrow or later after you post your effort.
Free the weed!! Class B to class C is not good enough!!
And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi
Sounds interesting, will work on it! Not very familiar with templates though!
Bored again. Wifes out tonight. heres my solution. wheres yours?
uurgh someone do a decent syntax colouring!!Code:PHP Code:
#ifndef LIMITED_VALUE_H #define LIMITED_VALUE_H #include <string> namespace LimitedV { // need an enum to differentiate between a min violation and a max violation. enum Violation_type ( Min_violation, Max_violation ); // now the policy class that specifies min/max values for type and exception // to be thrown on violation. template < typename Rep, Rep Min_value, Rep Max_value, typename Exception_type > class throw_exception_policy { public: static Rep Min() { return Min_Value; } static Rep Max() { return Max_Value; } static void OnError( Rep Value_set, Rep Original_value, Violation_type Violation ) { throw Exception_type; } typedef Rep Value_type; }; // Notice we sent in three params to our policy OnError function and used none of them. // but it makes it so much easier to add a different policy but where we need these arguments. // They are... the value you tried to set to, the original value, and the violation type. // In fact I have some spare time so I'll do another policy class to show how to use these args. template < typename Rep, Rep Min_value, Rep Max_value, typename Exception_type > class throw_verbose_exception_policy { public: static Rep Min() { return Min_Value; } static Rep Max() { return Max_Value; } static void OnError( Rep Value_set, Rep Original_value, Violation_type Violation ) { // ok here we will format a string object and use it to construct the exception // to use this policy ExceptionType must be able to be constructed from a std::string std::string what( "Exception :- " ); if ( Violation == Min_violation ) what += " minimum bound exceeded. Original value = " + Original_value + " Value attempted to set = " + Value_set + " Min for type = " + Min(); if ( Violation == Max_violation ) what += " maximum bound exceeded. Original value = " + Original_value + " Value attempted to set = " + Value_set + " Max for type = " + Max(); throw Exception_type( what ); } typedef Rep Value_type; }; // Now for the host class. This class will use the above policy to validate its data.For a // policy class to be supported by this class then it must have as members AT LEAST those // three functions and also the typedef Value_type template < typename Policy_class > class Limited_Value { public: typedef typename Policy_class::Value_type Value_type; Limited_Value( Value_type value ) { Set( value ); } const Limited_Value& operator = ( value_type value ) { Set( value ); return *this; } operator Value_type()const { return value_; } static Value_type Min() { return Policy_class::Min(); } static Value_type Max() { return Policy_class::Max(); } private: void Set( Value_type value; ) { if( value < Min() ) { Policy_class::OnError( value, value_ , Min_violation ); return; // ok so the above policies will throw but maybe another wont so really need this return } if ( value > Max() ) { Policy_class::OnError( value, value_, Max_violation ); return; // ditto } value_ = value; } Value_type value_; }; } #endif // inclusion guard.
Free the weed!! Class B to class C is not good enough!!
And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi
Theres a plugin for PHP boards that will make the code contained in [code] tags colored, it would be nice to have here.
I tried your challenge just because I was bored. It took me about half an hour. I could have made it more complex but.... no This is enough.
Its very extensible (I think).
Output:Code:#include <stdio.h> #include <iostream> using namespace std; enum BoundsBehavior { KEEP_NEW_VALUE, KEEP_OLD_VALUE, SNAP_TO_BOUNDS }; enum OutOfBounds { UNDER_BOUNDS, OVER_BOUNDS }; template <class DataType> struct Bounds { DataType min, max; }; template <class DataType, DataType min, DataType max, template <class DummyType> class HandlerType, BoundsBehavior boundsBehavior=KEEP_NEW_VALUE> class BoundsPolicy { public: typedef BoundsPolicy <DataType, min, max, HandlerType, boundsBehavior> ThisType; DataType value; Bounds <DataType> bounds; HandlerType <DataType> handler; BoundsPolicy() { bounds.min=min; bounds.max=max; } operator DataType () { return value; } DataType operator = (DataType newValue) { if (boundsBehavior==KEEP_NEW_VALUE) { value=newValue; if (value<min) handler(value, bounds, UNDER_BOUNDS); if (value>max) handler(value, bounds, OVER_BOUNDS); } else if (boundsBehavior==KEEP_OLD_VALUE) { if (newValue<min) handler(newValue, bounds, UNDER_BOUNDS); if (newValue>max) handler(newValue, bounds, OVER_BOUNDS); else value=newValue; } else // SNAP_TO_BOUNDS { if (newValue<min) { value=min; handler(newValue, bounds, UNDER_BOUNDS); } else if (newValue>max) { value=max; handler(newValue, bounds, OVER_BOUNDS); } else value=newValue; } return value; } friend ostream &operator << (ostream &stream, ThisType &data) { return stream << data.value; } friend istream &operator >> (istream &stream, ThisType &data) { register DataType temp; stream >> temp; data=temp; return stream; } }; template <class DataType> class BoundsException { public: typedef BoundsException <DataType> ThisType; char *format; char message[128]; DataType value; Bounds <DataType> bounds; OutOfBounds direction; BoundsException() { if (typeid(DataType)==typeid(int)) format="Out of Bounds Exception: value=%i; range=(%i, %i); direction=%i;"; else if (typeid(DataType)==typeid(float)) format="Out of Bounds Exception: value=%f; range=(%f, %f); direction=%i;"; else format="Out of Bounds Exception"; } void operator () (DataType value, Bounds <DataType> bounds, OutOfBounds direction) { this->value=value; this->bounds=bounds; this->direction=direction; sprintf(message, format, value, bounds.min, bounds.max, direction); throw *this; } friend ostream &operator << (ostream &stream, ThisType &exception) { return stream << exception.message; } }; int main() { BoundsPolicy <int, 0, 10, BoundsException, KEEP_OLD_VALUE> num; num=5; try { cout << "Current value: " << num << endl << "Range: (" << num.bounds.min << ", " << num.bounds.max << ')' << endl << "New value: "; cin >> num; cout << endl; } catch (BoundsException <int> exception) { cout << exception << endl; } cout << "Finally, the value is: " << num << endl; cout << endl; system("pause"); return 0;
Code:Current value: 5 Range: (0, 10) New value: 34 Out of Bounds Exception: value=34; range=(0, 10); direction=1; Finally, the value is: 5 Press any key to continue . . .
Last edited by Speedy5; 03-11-2003 at 06:20 PM.