473,503 Members | 13,381 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Value restriction


Here's a little pickle I've been pondering over. I've simplified it down for
posting, here goes:
Consider a function as simple (and as dumb) as the following:
bool IsAfter1998(Year year)
{
return (year > 1998);
}

So let's define the "Year" type. We start off with:
typedef int Year;
I want to restrict the value of a "Year" to not being 0 ( 1 BC is followed
by 1 AD). I've started off with this:
class Year
{
private:

int data;

void Set(int year)
{
if ( year == 0 ) throw bad_year();

data = year;
}

public:

class bad_year {};

explicit Year(int year = 1)
{
Set(year);
}

Year& operator=(Year year)
{
Set(year);

return *this;
}

operator int()
{
return data;
}

};
I figured a lot of people have probably done something like this before. So
can anyone suggest any suitable alternatives or maybe tweek my code a
little?

Particularly with my code, I realize that one can't do the following:

Year year;

++year;
-JKop
Jul 22 '05 #1
9 1516
JKop wrote:
Here's a little pickle I've been pondering over. I've simplified it down for
posting, here goes:
Consider a function as simple (and as dumb) as the following:
bool IsAfter1998(Year year)
{
return (year > 1998);
}

So let's define the "Year" type. We start off with:
typedef int Year;
I want to restrict the value of a "Year" to not being 0 ( 1 BC is followed
by 1 AD). I've started off with this:
class Year
{
private:

int data;

void Set(int year)
{
if ( year == 0 ) throw bad_year();

data = year;
}

public:

class bad_year {};

explicit Year(int year = 1)
{
Set(year);
}

Year& operator=(Year year)
{
Set(year);

return *this;
}

operator int()
{
return data;
}

};
I figured a lot of people have probably done something like this before. So
can anyone suggest any suitable alternatives or maybe tweek my code a
little?

Particularly with my code, I realize that one can't do the following:

Year year;

++year;
-JKop


I love integers:
Year sci_fic;
sci_fic = -20;
sci_fic++;
sci_fic--;
sci_fic /= 40;

By the way, you could use _unsigned_int_ if you
want the compiler to restrict the year to postive
values.

One idea is to have an inline function that validates
a year:
inline Validate_Year(unsigned int year)
{
if (year < 1)
throw Your_Favorite_Exception();
return;
}

I believe this would have minimal impact since it
is declared as inline.

I don't see any need to complicate the code by
creating a separate year class. Nor, IMHO, any
special reason to make the year a separate type.
--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #2
Thomas Matthews wrote:
By the way, you could use _unsigned_int_ if you
want the compiler to restrict the year to postive
values.


He doesn't want to restrict to positive, he wants to restrict to
*NON-ZERO*. Slightly different.
Jul 22 '05 #3

"JKop" <NU**@NULL.NULL> wrote in message news:tV*****************@news.indigo.ie...

Here's a little pickle I've been pondering over. I've simplified it down for
posting, here goes:
typedef int Year;


Your copy constructor seems a bit spurious. If you can't construct an invalid year
object, how could you ever get an invalid one to copy?

I detest implicit conversion operators.

Yes, you are going to have to define mathematic operators. Think about how pointers/iterators
work. The subtraction of two years is some integral type, but years should not otherwise implicitly
convert to/from numerics.

Jul 22 '05 #4
Ron Natalie posted:

Your copy constructor seems a bit spurious. If you can't construct an invalid year object, how could you ever get an invalid one to copy?
If by spurious you mean absent, then yes.

What you think of my assignment operator?

I detest implicit conversion operators.

Yes, you are going to have to define mathematic operators. Think about how pointers/iterators work. The subtraction of two years is some integral type, but years should not otherwise implicitly convert to/from numerics.


I disagree: a year *is* a number. Anyway, that was just an
example.

I wonder if it'd be appropriate to increment -1 to 1?

Year& operator++()
{
return ( data == -1 ? data = 1 : data += 1 );
}

Year& operator--()
{
return ( data == 1 ? data = -1 : data -= 1 );
}
-JKop
Jul 22 '05 #5
Year& operator++()
{
return ( data == -1 ? data = 1 : data += 1 );
}

Year& operator--()
{
return ( data == 1 ? data = -1 : data -= 1 );
}


Opps!
Year& operator++()
{
data == -1 ? data = 1 : data += 1 ;

return *this;
}

Year& operator--()
{
data == 1 ? data = -1 : data -= 1 ;

return *this;
}
-JKop
Jul 22 '05 #6
JKop wrote:

Ron Natalie posted:
Your copy constructor seems a bit spurious. If you can't construct an
invalid year object, how could you ever get an invalid

one to copy?

If by spurious you mean absent, then yes.

What you think of my assignment operator?


I think it is not needed.
One of the premises is that it is impossible to create
an invalid Year object. So whetever is passed to the assignment
operator *must* be a valid Year object. Thus the test if it
is valid is not neccessary. A simple assignment of the data
member is sufficient. But this is what the compiler generated
operator does anyway, so it is better to let the compiler take
care of op= instead of writing your own.

I wonder if it'd be appropriate to increment -1 to 1?
Sure, why not.

Year& operator++()
{
return ( data == -1 ? data = 1 : data += 1 );
}
But not like this.
it needs to return *this.

Year& operator--()
{
return ( data == 1 ? data = -1 : data -= 1 );
}


Same. return *this;

With other operators there is a problem on the horizon.

The problem I see is this: What is the return value of op- ?
Is it Year? Well, in every day speaking we say so, but is that really
true. Is a YearSpan the same thing as a Year?
Lets take the conservative approach and say: No. The result of
subtracting 1960 from 1940 is not a Year object, but a YearSpan object.
That makes sense, since adding 1940 with 1980 doesn't really make sense.
But adding 40 years (a YearSpan object) to 1980 makes perfectly sense.

What about op* and op- ?
Does it make sense to calulate 1940 * 1980 ?
I would say no. But it would make sense to allow op/ and op* for
a YearSpan object. 1940 + 2 * 40_years seems reasonable: add 2 times
the amount of 40 years (as YearSpan) to 1940.

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #7
Have the C++ dudes considered "allowing" the following?:
class Year : public int
{
// Hijack the constructor and all the = operators, += -= *=
/= etc.

}
Ofcourse you wouldn't have any virtual members, but that
wouldn't be a problem:

bool IsAfter1998(Year year)
{
return (year > 1998)
}
I hear in other languages you can inherit from the
intrinsic types... no?

Actually, right now this moment I've thought of an
alternative:

class Int
{
//All sorts of operators

operator int+() //...

};
class Year : public Int ...
Just create an Int class that acts EXACTLY like an int...
(but maybe give it defined overflow behavior ;-) )
-JKop
Jul 22 '05 #8
> operator int+() //...

TYPO

operator int()
-JKop
Jul 22 '05 #9
JKop wrote:

Have the C++ dudes considered "allowing" the following?:

class Year : public int
{
// Hijack the constructor and all the = operators, += -= *=
/= etc.

}


Sorry. That's not allowed :-)

--
Karl Heinz Buchegger
kb******@gascad.at
Jul 22 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
3584
by: Matthet | last post by:
Hi, I'm defining an element that is based on simpleType named "myPatternType" <xsd:element name="MyElement"> <xsd:complexType> <xsd:simpleContent> <xsd:extension base="myPatternType">...
0
1473
by: Ingrid | last post by:
Am I right in thinking that datatyping at element level ie <xs:element name="num" type="xs:integer"> and specifying a choice of attribute values ie <xs:attribute name="kind"> <xs:simpleType>...
4
2914
by: Lénaïc Huard | last post by:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hello, I've some namespace problems when defining default values for attributes. My problem seems to come from the fact that the attributes are...
1
4390
by: Joyce | last post by:
In my schema I have 2 enumerations, let's say, country description and country code, and I want to use them so I can map each country description to its precise country code (and no other). So far...
2
1533
by: ocelka | last post by:
I need know how define xml schema for this xml fragment: <set name="person-id" value="secure-card"/> <set name="person-id" value="thumb-print"/> <set name="length-unit" value="inch"/> <set...
0
2173
by: Douha | last post by:
Hi all, I have an XML file where all to elements for the data are contained in CDATA sections. I have a schema created that is working right now although it is pretty dumbed down. I have a need...
1
4971
by: Stefano G. | last post by:
I have a WSDL containing this enumeration type <xsd:simpleType name="item_type_enum"> <xsd:restriction base="xsd:string"> <xsd:enumeration value="VCD"/> <xsd:enumeration value="SVCD"/>...
13
10087
by: dbuchanan | last post by:
Hello, Here is the error message; ---------------------------- Exception Message: ForeignKeyConstraint Lkp_tbl040Cmpt_lkp302SensorType requires the child key values (5) to exist in the...
1
2163
by: Stanimir Stamenkov | last post by:
This is an issue I've got using the Xerces-J 2.7.1 release when loading the following schema: <?xml version="1.0" ?> <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element...
6
4260
by: burkley | last post by:
In XML Schema, is it possible to derive a complex type via restriction and have the new derived type be in a different namespace than the original base type? I've banged on this for 2 days now...
0
7213
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
7098
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
7298
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
7366
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
1
7017
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
1
5026
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...
0
3187
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The...
0
1526
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated ...
0
406
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.