C++Boost Operators














































C++Boost Operators



Header: "boost/operators.hpp"

There are a number of base classes that comprise the Operators library. Each class contributes operators according to the concept it names. You use them by inheriting from themmultiply inheriting if you need the services of more than one. Fortunately, there are some composite concepts defined in Operators obviating the need to multiply inherit for many common cases. The following synopses describe some of the most commonly used Operator classes, the concepts they represent, and the demands they place on classes derived from them. In some cases, the requirements for the actual concepts are not the same as the requirements for the concept base classes when using Operators. For example, the concept addable requires that there be an operator T operator+(const T& lhs,const T& rhs) defined, but the Operators base class addable instead requires a member function, T operator+=(const T& other). Using this member function, the base class addable augments the derived class with operator+. Throughout the synopses, the concepts are always stated first, followed by the type requirements for classes deriving from them.

less_than_comparable:The less_than_comparable concept requires the following semantics for a type T.

 bool operator<(const T&,const T&);  bool operator>(const T&,const T&);  bool operator<=(const T&,const T&); bool operator>=(const T&,const T&); 

When deriving from boost::less_than_comparable, the derived class (T) must provide the equivalent of

 bool operator<(const T&, const T&);  

Note that the return type need not be exactly bool, but it must be implicitly convertible to bool. For the concept LessThanComparable found in the C++ Standard, operator< is required, so classes derived from less_than_comparable need to comply with that requirement. In return, less_than_comparable implements the three remaining operators in terms of operator<.

equality_comparable:The equality_comparable concept requires the following semantics for a type T.bool operator==(const T&,const T&); bool operator!=(const T&,const T&); When deriving from boost::equality_comparable, the derived class (T) must provide the equivalent of bool operator==(const T&,const T&); Again, the return type needn't be bool, but it must be a type implicitly convertible to bool. For the concept Equality Comparable in the C++ Standard, operator== is required, so derived classes from equality_comparable need to comply with that requirement. The class equality_comparable equips T with bool operator!=(const T&,const T&).
addable:The addable concept requires the following semantics for a type TT operator+(const T&,const T&); T operator+=(const T&); When deriving from boost::addable, the derived class (T) must provide the equivalent ofT operator+=(const T&); The return type must be implicitly convertible to T. The class addable equips T with T operator+(const T&,const T&).
subtractable: The subtractable concept requires the following semantics for a type TT operator-(const T&,const T&); T operator+=(const T&); When deriving from boost::subtractable, the derived class (T) must provide the equivalent of T operator-=(const T&,const T&); The return type must be implicitly convertible to T. The class subtractable equips T with T operator-(const T&,const T&).
orable: The orable concept requires the following semantics for a type TT operator|(const T&,const T&); T operator|=(const T&,const T&); When deriving from boost::orable, the derived class (T) must provide the equivalent oT operator|=(const T&,const T&); The return type must be implicitly convertible to T. The class orable equips T with T operator|(const T&,const T&).
andable: The andable concept requires the following semantics for a type TT operator&(const T&,const T&); T operator&=(const T&,const T&); When deriving from boost::andable, the derived class (T) must provide the equivalent of   T operator&=(const T&,const T&); The return type must be implicitly convertible to T. The class andable equips T with T operator&(const T&,const T&).
incrementable: The incrementable concept requires the following semantics for a type TT& operator++(T&); T operator++(T&,int); When deriving from boost::incrementable, the derived class (T) must provide the equivalent of T& operator++(T&); The return type must be implicitly convertible to T. The class incrementable equips T with T operator++(T&,int).
decrementable: The decrementable concept requires the following semantics for a type T.T& operator--(T&); T operator--(T&,int); When deriving from boost::decrementable, the derived class (T) must provide the equivalent of T& operator--(T&); The return type must be implicitly convertible to T. The class decrementable equips T with T operator--(T&,int).
equivalent: The equivalent concept requires the following semantics for a type Tbool operator<(const T&,const T&); bool operator==(const T&,const T&); When deriving from boost::equivalent, the derived class (T) must provide the equivalent of bool operator<(const T&,const T&); The return type must be implicitly convertible to bool. The class equivalent equips T with T operator==(const T&,const T&). Note that equivalence and equality are, by definition, different beasts; two objects that are equivalent aren't necessarily equal. However, for the purposes of the equivalent concept, they are the same.
dereferenceable: The dereferenceable concept requires the following semantics for a type T, assuming that T is the operand, R is the reference type, and P is a pointer type (for example, T is an iterator type, R is a reference to the iterator's value_type, and P is a pointer to the iterator's value_type). P operator->() const; R operator*() const; When deriving from boost::dereferenceable, the derived class (T) must provide the equivalent of  R operator*() const; Additionally, the unary operator& for R must be implicitly convertible to P. This means that R doesn't actually need to be the reference typeit can just as well be a proxy class. The class dereferenceable equips T with P operator->() const.
indexable:The indexable concept requires the following semantics for a type T, assuming that T is the operand, R is the reference type, P is a pointer type, and D is the difference_type (for example, T is an iterator type, R is a reference to the iterator's value_type, P is a pointer to the iterator's value_type, and D is the difference_type).R operator[](D) const; R operator+(const T&,D); When deriving from boost::indexable, the derived class (T) must provide the equivalent of R operator+(const T&,D); The class indexable equips T with R operator[](D) const.



Example of C++ Boost Operator:

#include <iostream>

#include <cmath>

#include <cassert>

#include <boost/operators.hpp>


class Vectr3D: public boost::less_than_comparable<Vectr3D>

   , public boost::addable<Vectr3D, double>

{

private:

double m_x, m_y, m_z;

public:

Vectr3D(double x, double y, double z);

double norm() const;


// Stream insertion operator => Make class printable 

friend std::ostream& operator<<(std::ostream& os, Vectr3D const& vec);

// Required by: boost::less_than_comparable<Vectr3D>

// From this operator, boost implements the operators (<=), (>), (>=)

friend bool operator<(Vectr3D const& lhs, Vectr3D const& rhs);


// Required by: boost::addable<Vectr3D, double>

// Boost implements: operator+(Vectr3D, double) and operator+(double, Vectr3D)

friend Vectr3D& operator+=(Vectr3D& lhs, double rhs);

};


template<typename variable_t>

void disp(const char* variableName, variable_t const& value)

{

std::cout << " =>> " << variableName << " = " << value << "\n";

}


int main(){


Vectr3D v1 = {3, 5, 6};

Vectr3D v2 = {12, 5, 9};

std::cout << std::boolalpha;

disp("v1", v1); disp("v2", v2);

disp("v1.norm()", v1.norm());

disp("v2.norm()", v2.norm());


std::cout << "\n EXPERIMENT 1 boost::less_than_comparable<Vectr3D>" << "\n";

std::cout << "--------------------------------------------------" << "\n";


std::cout << "[a] v1 <  v2 = " << (v1 < v2) << "\n";

std::cout << "[b] v1 <  v2 = " << operator<(v1, v2) << "\n\n";   

std::cout << "[a] v1 <= v2 = " << (v1 <= v2) << "\n";

std::cout << "[b] v1 <= v2 = " << operator<=(v1, v2) << "\n\n";

std::cout << "[a] v1 >  v2 = " << (v1 > v2) << "\n";

std::cout << "[b] v1 >  v2 = " << operator>(v1, v2) << "\n\n";

std::cout << "[a] v1 >=  v2 = " << (v1 >= v2) << "\n";

std::cout << "[b] v1 >=  v2 = " << operator>=(v1, v2) << "\n\n";


std::cout << "\n EXPERIMENT 2 boost::less_than_comparable<Vectr3D>" << "\n";

std::cout << "--------------------------------------------------" << "\n";

disp("v1 + 5.0", v1 + 5.0);

disp("operator+(v1, 5.0)", operator+(v1, 5.0));

disp("5.0 + v1", 5.0 + v1);

disp("operator+(5.0, v1", operator+(5.0, v1));

disp("v1", v1);

return 0;

}


Vectr3D::Vectr3D(double x, double y, double z)

: m_x(x), m_y(y), m_z(z)

{

}


double

Vectr3D::norm() const 

{

return std::sqrt(m_x * m_x + m_y * m_y + m_z * m_z);

}


std::ostream&

operator<<(std::ostream& os, Vectr3D const& vec)

{

return os << "Vectr3D{ "

  << " x = "   << vec.m_x

  << " ; y = " << vec.m_y

  << " ; z = " << vec.m_z

  << " } ";

}


bool

operator<(Vectr3D const& lhs, Vectr3D const& rhs)

{

return lhs.norm() < rhs.norm();

}


Vectr3D&

operator+=(Vectr3D& lhs, double rhs)

{

double  d = rhs;

lhs = {lhs.m_x + d, lhs.m_y + d, lhs.m_z + d};

return lhs;

}


Output:

 =>> v1 = Vectrtr3D{  x = 3 ; y = 5 ; z = 6 } 
 =>> v2 = Vec3D{  x = 12 ; y = 5 ; z = 9 } 
 =>> v1.norm() = 8.3666
 =>> v2.norm() = 15.8114

 EXPERIMENT 1 boost::less_than_comparable<Vectr3D>
--------------------------------------------------
[a] v1 <  v2 = true
[b] v1 <  v2 = true

[a] v1 <= v2 = true
[b] v1 <= v2 = true

[a] v1 >  v2 = false
[b] v1 >  v2 = false

[a] v1 >=  v2 = false
[b] v1 >=  v2 = false


 EXPERIMENT 2 boost::less_than_comparable<Vectr3D>
--------------------------------------------------
 =>> v1 + 5.0 = Vectr3D{  x = 8 ; y = 10 ; z = 11 } 
 =>> operator+(v1, 5.0) = Vectr3D{  x = 8 ; y = 10 ; z = 11 } 
 =>> 5.0 + v1 = Vectr3D{  x = 8 ; y = 10 ; z = 11 } 
 =>> operator+(5.0, v1 = Vectr3D{  x = 8 ; y = 10 ; z = 11 } 
 =>> v1 = Vectr3D{  x = 3 ; y = 5 ; z = 6 } 

euclidean_ring_operators

totally_ordered













More Articles of Rupsi Kumari:

Name Views Likes
C++Boost Operators 239 0
Triply linked list 1385 1
C++Boost::operators 277 0

Comments