Postfix Call Examples


Weight

Comparison of weight units.

C∀C++
struct Weight {
	double stones;
};


Weight ?+?( Weight l, Weight r ) {
	return l.stones + r.stones;
}
Weight ?`st( double w ) { return w; }
double ?`st( Weight w ) { return w.stones; }
Weight ?`lb( double w ) { return w / 14.0; }
double ?`lb( Weight w ) { return w.stones * 14.0; }
Weight ?`kg( double w ) { return w / 6.35; }
double ?`kg( Weight w ) { return w.stones * 6.35; }
int main() {
	Weight w, heavy = { 20 }; // stones
	w = 155`lb;
	w = 0b_1111`st;
	w = 0_233`lb;
	w = 0x_9b_u`kg;
	w = 5.5`st + 8`kg + 25.01`lb + heavy;
}
struct Weight {
	double stones;
	Weight() {}
	Weight( double w ) { stones = w; }
};
Weight operator+( Weight l, Weight r ) {
	return l.stones + r.stones;
}
Weight operator""_st( long double w ) { return w; }
Weight operator""_lb( long double w ) { return w / 14.0; }
Weight operator""_kg( long double w ) { return w / 6.35; }
Weight operator""_st( unsigned long long int w ) { return w; }
Weight operator""_lb( unsigned long long int w ) { return w / 14.0; }
Weight operator""_kg( unsigned long long int w ) { return w / 6.35; }
int main() {
	Weight w, heavy = { 20 }; // stones
	w = 155_lb;
	w = 0b1111_lb;
	w = 0'233_lb;		// quote separator
	w = 0x9b_kg;
	w = 5.5d_st + 8_kg + 25.01_lb + heavy;
}

A common example for postfix functions is converting basic literals into user literals. The C∀ example (left) stores a mass in units of stones (1 stone = 14 lb or 6.35 kg) and provides an addition operator ?+? (imagine a full set of arithmetic operators). The arithmetic operators manipulate stones and the postfix operations convert to/from different units. The three postfixing function names st, lb, and kg, represent units stones, pounds, and kilograms, respectively. Each name has two forms that bidirectional convert: a value of a specified unit to stones, e.g., w = 14`lbw == 1 stone or a Weight from stones back to specific units, e.g., w`lb (1 stone) to 14.

The C++ example (right) provides a restricted capability via user literals. The operator"" only takes a constant argument (i.e., no variable as an argument), and the constant type must be the highest-level constant-type, e.g., long double for all floating-point constants. As well, there is no constant conversion, i.e., int to double constants, so integral constants are handled by a separate set of routines, with maximal integral type unsigned long long int. Finally, there is no mechanism to use this syntax for a bidirectional conversion because operator"" only accepts a constant argument.


Time

Comparison of time units.

C∀C++
#include <fstream.hfa>
#include <time.hfa>


Duration s = 1`h + 2 * 10`m + 70`s / 10;
sout | "1 hour + 2*10 min + 70/10 sec = " | s | "seconds";
sout | "Dividing that by 2 minutes gives" | s / 2`m;
sout | "Dividing that by 2 gives" | s / 2 | "seconds\n";
sout | s | "seconds is"
	  | s`h | "hours,"
	  | (s % 1`h)`m | "minutes,"
	  | (s % 1`m)`s | "seconds";
#include <iostream>
#include <chrono>
using namespace std;
using namespace std::chrono;
seconds s = hours(1) + 2 * minutes(10) + seconds(70) / 10;
cout << "1 hour + 2*10 min + 70/10 sec = " << s.count() << " seconds\n";
cout << "Dividing that by 2 minutes gives " << s / minutes(2) << '\n';
cout << "Dividing that by 2 gives " << (s / 2).count() << " seconds\n";
cout << s.count() << " seconds is "
	  << duration_cast<hours>( s ).count() << " hours, "
	  << duration_cast<minutes>( s % hours(1) ).count() << " minutes, "
	  << duration_cast<seconds>( s % minutes(1) ).count() << " seconds\n";