1 #include <CGAL/IO/io.h>
2 #include <CGAL/Algebraic_structure_traits.h>
3 #include <CGAL/number_utils.h>
4 #include <CGAL/int.h>
5 
6 template< typename NT > NT unit_part(const NT& x);
7 template< typename NT >
8 NT unit_part_(const NT& x, CGAL::Field_tag);
9 template< typename NT >
10 NT unit_part_(const NT& x, CGAL::Integral_domain_without_division_tag);
11 
12 template< typename NT >
unit_part(const NT & x)13 NT unit_part(const NT& x){
14     // the unit part of 0 is defined as 1.
15     if (x == 0 ) return NT(1);
16 
17     typedef CGAL::Algebraic_structure_traits<NT> AST;
18     typedef typename AST::Algebraic_category Algebraic_category;
19     return unit_part_(x,Algebraic_category());
20 }
21 
22 template< typename NT >
unit_part_(const NT & x,CGAL::Integral_domain_without_division_tag)23 NT unit_part_(const NT& x, CGAL::Integral_domain_without_division_tag){
24     // For many other types the only units are just -1 and +1.
25     return NT(int(CGAL::sign(x)));
26 }
27 
28 template< typename NT >
unit_part_(const NT & x,CGAL::Field_tag)29 NT unit_part_(const NT& x, CGAL::Field_tag){
30     // For Fields every x != 0 is a unit.
31     // Therefore, every x != 0 is its own unit part.
32     return x;
33 }
34 
main()35 int main(){
36     // Function call for a model of EuclideanRing, i.e. int.
37     std::cout<< "int:    unit_part(-3  ): " << unit_part(-3  ) << std::endl;
38     // Function call for a model of FieldWithSqrt, i.e. double
39     std::cout<< "double: unit_part(-3.0): " << unit_part(-3.0) << std::endl;
40     return 0;
41 }
42 
43 // Note that this is just an example
44 // This implementation for unit part won't work for some types, e.g.,
45 // types that are not RealEmbeddable or types representing structures that have
46 // more units than just -1 and +1. (e.g. MP_Float representing Z[1/2])
47 // From there Algebraic_structure_traits provides the functor Unit_part.
48 
49