]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/safe_numerics/test/test_z.cpp
import quincy beta 17.1.0
[ceph.git] / ceph / src / boost / libs / safe_numerics / test / test_z.cpp
1
2 #if 0
3 auto val()
4 {
5 return -0xFFFFFFFF;
6 }
7
8 #include <stdexcept>
9 #include <iostream>
10 #include <boost/safe_numerics/safe_integer.hpp>
11 #include <boost/safe_numerics/safe_integer_literal.hpp>
12
13 void val0(){
14 const boost::safe_numerics::safe<unsigned int> x{0};
15 std::cout << x << std::endl;
16 std::cout << -x << std::endl;
17 auto y = -x;
18 std::cout << y << std::endl;
19 }
20
21 constexpr boost::safe_numerics::safe<unsigned int> val1()
22 {
23 constexpr boost::safe_numerics::safe<unsigned int> x = 0xFFFFFFFF;
24 return -x;
25 }
26 constexpr boost::safe_numerics::safe<unsigned int> val2()
27 {
28 boost::safe_numerics::safe<unsigned int> x = - boost::safe_numerics::safe_unsigned_literal<0xFFFFFFFF>();
29 return x;
30 }
31
32 constexpr boost::safe_numerics::safe<unsigned int> val3()
33 {
34 return - boost::safe_numerics::safe_unsigned_literal<0xFFFFFFFF>();
35 }
36
37 int main(){
38 val0();
39 std::cout << val1() << std::endl;
40 std::cout << val2() << std::endl;
41 std::cout << val3() << std::endl;
42 return 0;
43 }
44
45 // test utility
46 #include <boost/safe_numerics/utility.hpp>
47
48 int main(){
49 using namespace boost::safe_numerics;
50 using x = unsigned_stored_type<0, 42>;
51 print_type<x> p1;
52
53 return 0;
54 }
55
56 // test automatic type promotion
57 #include <boost/safe_numerics/automatic.hpp>
58 #include <boost/safe_numerics/safe_integer.hpp>
59 #include <type_traits>
60 #include <cstdint>
61 #include <iostream>
62
63 int main(){
64 using namespace boost::safe_numerics;
65 using ar = automatic::addition_result<std::uint8_t, std::uint8_t>;
66 static_assert(
67 std::is_same<ar::type, std::uint16_t>::value,
68 "sum of two 8 bit unsigned integers should fit in on 16 bit unsigned integer"
69 );
70 return 0;
71 }
72
73
74 // test automatic type promotion
75 #include <boost/safe_numerics/safe_integer.hpp>
76 #include <boost/safe_numerics/safe_integer_range.hpp>
77 #include <boost/safe_numerics/safe_integer_literal.hpp>
78 #include <boost/safe_numerics/automatic.hpp>
79 #include <type_traits>
80 #include <cstdint>
81 #include <iostream>
82
83 int main(){
84 using namespace boost::safe_numerics;
85 unsigned char t1 = 1;
86 constexpr const safe_unsigned_literal<42, automatic, default_exception_policy> v2;
87 using result_type = decltype(t1 + v2);
88
89 static_assert(
90 std::is_same<
91 result_type,
92 safe_unsigned_range<42, 297, automatic, default_exception_policy>
93 >::value,
94 "result type should have a range 42-297"
95 );
96 return 0;
97 }
98 void f1(){
99 using namespace boost::safe_numerics;
100 constexpr safe<int> j = 0;
101 constexpr safe<int> k = 3;
102 constexpr safe<int> l = j + k; // compile error
103 }
104
105 void f2(){
106 using namespace boost::safe_numerics;
107 constexpr safe<int> j = boost::safe_numerics::safe_signed_literal<0>();
108 constexpr safe<int> k = boost::safe_numerics::safe_signed_literal<3>();
109 constexpr safe<int> l = j + k; // compile error
110 }
111
112 void f3(){
113 using namespace boost::safe_numerics;
114 constexpr auto j = safe_signed_literal<0, native, loose_trap_policy>();
115 constexpr auto k = safe_signed_literal<3>();
116 constexpr const safe<int> l = j + k;
117 }
118
119 void f4(){
120 using namespace boost::safe_numerics;
121 safe_signed_literal<0, native, loose_trap_policy> j;
122 safe_signed_literal<3> k;
123 constexpr auto l = safe_signed_literal<3>();
124 constexpr const safe<int> l2 = j + k;
125 }
126
127 #include <boost/safe_numerics/interval.hpp>
128
129 int main(){
130 return 0;
131 }
132
133 #include <boost/safe_numerics/utility.hpp>
134 #include <boost/safe_numerics/cpp.hpp>
135 #include <boost/safe_numerics/safe_common.hpp>
136
137 using pic16_promotion = boost::safe_numerics::cpp<
138 8, // char
139 8, // short
140 8, // int
141 16, // long
142 32 // long long
143 >;
144
145 #include <type_traits>
146 #include <boost/safe_numerics/safe_integer.hpp>
147 #include <boost/safe_numerics/range_value.hpp>
148 #include <iostream>
149
150 int main(){
151 using namespace boost::safe_numerics;
152 static_assert(
153 std::is_literal_type<safe<int>>::value,
154 "safe type is a literal type"
155 );
156 static_assert(
157 std::is_literal_type<interval<int>>::value,
158 "interval type is a literal type"
159 );
160 static_assert(
161 std::is_literal_type<interval<
162 safe<int>
163 >>::value,
164 "interval of safe types is a literal type"
165 );
166 static_assert(
167 std::is_literal_type<range_value<
168 safe<int>
169 >>::value,
170 "range_value of safe types is a literal type"
171 );
172 safe<int> x = 42;
173 std::cout << make_range_value(x);
174 return 0;
175 }
176
177 auto val()
178 {
179 return -0xFFFFFFFF;
180 }
181
182 #include <stdexcept>
183 #include <iostream>
184 #include <boost/safe_numerics/safe_integer.hpp>
185 #include <boost/safe_numerics/safe_integer_literal.hpp>
186
187 void val0(){
188 const boost::safe_numerics::safe<unsigned int> x{0};
189 std::cout << x << std::endl;
190 std::cout << -x << std::endl;
191 auto y = -x;
192 std::cout << y << std::endl;
193 }
194
195 constexpr boost::safe_numerics::safe<unsigned int> val1(){
196 constexpr boost::safe_numerics::safe<unsigned int> x = 0xFFFFFFFF;
197 return -x;
198 }
199 constexpr boost::safe_numerics::safe<unsigned int> val2(){
200 const boost::safe_numerics::safe<unsigned int> x
201 = -boost::safe_numerics::safe_unsigned_literal<0xFFFFFFFF>();
202 return x;
203 }
204 constexpr boost::safe_numerics::safe<unsigned int> val3(){
205 return - boost::safe_numerics::safe_unsigned_literal<0xFFFFFFFF>();
206 }
207
208 int main(){
209 val0();
210 std::cout << val1() << std::endl;
211 std::cout << val2() << std::endl;
212 std::cout << val3() << std::endl;
213 return 0;
214 }
215
216 #include <boost/logic/tribool.hpp>
217 #include <boost/safe_integer/checked_integer.hpp>
218 #include <boost/safe_integer/checked_result.hpp>
219 #include <boost/safe_integer/checked_result_operations.hpp>
220 #include <boost/safe_integer/interval.hpp>
221
222 namespace boost {
223 namespace safe_numerics {
224
225 template<class EP, typename R>
226 constexpr void
227 dispatch(const checked_result<R> & cr){
228 }
229
230 template<class T>
231 constexpr T base_value(const T & t){
232 return t;
233 }
234
235 template<typename R, R Min, R Max, typename E>
236 struct validate_detail {
237
238 constexpr static const interval<checked_result<R>> t_interval{
239 checked::cast<R>(base_value(std::numeric_limits<T>::min())),
240 checked::cast<R>(base_value(std::numeric_limits<T>::max()))
241 };
242 constexpr static const interval<checked_result<R>> r_interval{Min, Max};
243
244 /*
245 static_assert(
246 ! static_cast<bool>(r_interval.excludes(t_interval)),
247 "ranges don't overlap: can't cast"
248 );
249 */
250
251 struct exception_possible {
252 constexpr static R return_value(
253 const T & t
254 ){
255 static_assert(
256 ! static_cast<bool>(r_interval.includes(t_interval)),
257 "exeption not possible"
258 );
259 // INT08-C
260 const checked_result<R> r = checked::cast<R>(t);
261 dispatch<E>(r);
262 return base_value(r);
263 }
264 };
265 struct exception_not_possible {
266 constexpr static R return_value(
267 const T & t
268 ){
269 static_assert(
270 static_cast<bool>(r_interval.includes(t_interval)),
271 "exeption not possible"
272 );
273 return static_cast<R>(t);
274 }
275 };
276
277 static R return_value(const T & t){
278 return std::conditional<
279 static_cast<bool>(r_interval.includes(t_interval)),
280 exception_not_possible,
281 exception_possible
282 >::type::return_value(t);
283 }
284 };
285
286 template<typename R, R Min, R Max, typename T>
287 bool test1(const T & t){
288 const interval<checked_result<R>> t_interval{
289 checked::cast<R>(base_value(std::numeric_limits<T>::min())),
290 checked::cast<R>(base_value(std::numeric_limits<T>::max()))
291 };
292 const interval<checked_result<R>> r_interval{Min, Max};
293
294 /*
295 static_assert(
296 ! static_cast<bool>(r_interval.excludes(t_interval)),
297 "ranges don't overlap: can't cast"
298 );
299 */
300 const boost::logic::tribool tb1 = r_interval.includes(t_interval);
301 const bool x1 = tb1;
302
303 const boost::logic::tribool tb2 = r_interval.excludes(t_interval);
304 const bool x2 = tb2;
305 return x2;
306 }
307
308
309 } // safe_numerics
310 } // boost
311
312 int main(){
313 unsigned int x1 = boost::safe_numerics::test1<
314 unsigned int, 0, 100, signed char
315 >(-1);
316 bool x2 = boost::safe_numerics::validate_detail<
317 unsigned int, 0, 100, signed char, void
318 >::return_value(-1);
319 return 0;
320 }
321
322 using uint8_t = unsigned char;
323
324 enum class safe_numerics_error : uint8_t {
325 success = 0,
326 failure, // result is above representational maximum
327 error_count
328 };
329
330 template<typename R>
331 struct checked_result {
332 const safe_numerics_error m_e;
333 const union {
334 const R m_r;
335 char const * const m_msg;
336 };
337 constexpr /*explicit*/ checked_result(const R & r) :
338 m_e(safe_numerics_error::success),
339 m_r(r)
340 {}
341 constexpr /*explicit*/ checked_result(const safe_numerics_error & e) :
342 m_e(e),
343 m_msg("")
344 {}
345 };
346
347 // integers addition
348 template<class T>
349 constexpr inline checked_result<T> operator+(
350 const checked_result<T> & t,
351 const checked_result<T> & u
352 ){
353 #if 1 // compile fails
354 constexpr const safe_numerics_error x[2][2]{
355 // t == success
356 {
357 // u == ...
358 safe_numerics_error::success,
359 safe_numerics_error::failure
360 },
361 // t == positive_overflow_error,
362 {
363 // u == ...
364 safe_numerics_error::success,
365 safe_numerics_error::failure
366 }
367 };
368
369 // "Constexpr variable 'e' must be initialized by a constant expression"
370 constexpr const safe_numerics_error e = x
371 [static_cast<uint8_t>(t.m_e)]
372 [static_cast<uint8_t>(u.m_e)]
373 ;
374
375 return
376 safe_numerics_error::success == e
377 ? t.m_r + u.m_r
378 : checked_result<T>(e)
379 ;
380 #else // works as expected
381 constexpr const safe_numerics_error x[2][2]{
382 // t == success
383 {
384 // u == ...
385 safe_numerics_error::success,
386 safe_numerics_error::failure
387 },
388 // t == failure,
389 {
390 // u == ...
391 safe_numerics_error::failure,
392 safe_numerics_error::failure
393 }
394 };
395
396 return
397 safe_numerics_error::success == x
398 [static_cast<uint8_t>(t.m_e)]
399 [static_cast<uint8_t>(u.m_e)]
400 ? t.m_r + u.m_r
401 : checked_result<T>(x
402 [static_cast<uint8_t>(t.m_e)]
403 [static_cast<uint8_t>(u.m_e)]
404 )
405 ;
406 #endif
407 }
408
409 int main(){
410 constexpr const checked_result<unsigned> i = 0;
411 constexpr const checked_result<unsigned> j = 0;
412
413 constexpr const checked_result<unsigned> k = i + j;
414
415 // return k.m_r;
416
417 constexpr const checked_result<unsigned> i2 = safe_numerics_error::failure;
418 constexpr const checked_result<unsigned> j2 = 0;
419
420 constexpr const checked_result<unsigned> k2 = i2 + j2;
421 return k2.m_r;
422 }
423 #endif
424
425 #if 0
426 using uint8_t = unsigned char;
427
428
429 #if 1
430 enum class safe_numerics_error : uint8_t {
431 success = 0,
432 failure, // result is above representational maximum
433 error_count
434 };
435 #else
436 // avoiding enum class fails to solve problem
437 struct safe_numerics_error {
438 const uint8_t m_t;
439 constexpr const static uint8_t success = 0;
440 constexpr const static uint8_t failure = 1;
441 constexpr safe_numerics_error(uint8_t t) :
442 m_t(t)
443 {}
444 constexpr operator uint8_t () const {
445 return m_t;
446 }
447 };
448 #endif
449
450 template<typename R>
451 struct checked_result {
452 const safe_numerics_error m_e;
453 const union {
454 const R m_r;
455 char const * const m_msg;
456 };
457 constexpr /*explicit*/ checked_result(const R & r) :
458 m_e(safe_numerics_error::success),
459 m_r(r)
460 {}
461 constexpr /*explicit*/ checked_result(const safe_numerics_error & e) :
462 m_e(e),
463 m_msg("")
464 {}
465 };
466
467 // integers addition
468 template<class T>
469 constexpr inline checked_result<T> operator+(
470 const checked_result<T> & t,
471 const checked_result<T> & u
472 ){
473 // "Constexpr variable 'e' must be initialized by a constant expression"
474 constexpr const safe_numerics_error x[2][2]{
475 // t == success
476 {
477 // u == ...
478 safe_numerics_error::success,
479 safe_numerics_error::failure
480 },
481 // t == positive_overflow_error,
482 {
483 // u == ...
484 safe_numerics_error::failure,
485 safe_numerics_error::failure
486 }
487 };
488
489 #if 1 // compile fails
490 const safe_numerics_error e = x
491 [static_cast<uint8_t>(t.m_e)]
492 [static_cast<uint8_t>(u.m_e)]
493 ;
494
495 return
496 (safe_numerics_error::success == e)
497 ? t.m_r + u.m_r
498 : checked_result<T>(e)
499 ;
500 #else // works as expected
501 return
502 safe_numerics_error::success == x
503 [static_cast<uint8_t>(t.m_e)]
504 [static_cast<uint8_t>(u.m_e)]
505 ? t.m_r + u.m_r
506 : checked_result<T>(x
507 [static_cast<uint8_t>(t.m_e)]
508 [static_cast<uint8_t>(u.m_e)]
509 )
510 ;
511 #endif
512 }
513
514 int main(){
515 constexpr const checked_result<unsigned> i = 0;
516 constexpr const checked_result<unsigned> j = 0;
517
518 //constexpr const checked_result<unsigned> k = i + j;
519 // return k.m_r;
520
521 constexpr const checked_result<unsigned> i2 = safe_numerics_error::failure;
522 constexpr const checked_result<unsigned> j2 = 0;
523
524 constexpr const checked_result<unsigned> k2 = i2 + j2;
525 return 0;
526 }
527
528 #endif
529
530 #if 0
531 //#include "safe_common.hpp>
532 //#include "checked_result.hpp>
533 //#include "checked_default.hpp>
534 #include <cassert>
535 #include <boost/logic/tribool.hpp>
536
537 #include <iostream>
538
539 // note: Don't reorder these. Code in the file checked_result_operations.hpp
540 // depends upon this order !!!
541 enum class safe_numerics_error : std::uint8_t {
542 success = 0,
543 positive_overflow_error, // result is above representational maximum
544 negative_overflow_error, // result is below representational minimum
545 domain_error, // one operand is out of valid range
546 range_error, // result cannot be produced for this operation
547 precision_overflow_error, // result lost precision
548 underflow_error, // result is too small to be represented
549 negative_value_shift, // negative value in shift operator
550 negative_shift, // shift a negative value
551 shift_too_large, // l/r shift exceeds variable size
552 uninitialized_value // l/r shift exceeds variable size
553 };
554
555 // checked result is an "extended version" of the type R. That is it's domain is
556 // the domain of R U possible other values which might result from arithmetic
557 // operations. An example of such a value would be safe_error::positive_overflow_error.
558 template<typename R>
559 struct checked_result {
560 const safe_numerics_error m_e;
561 const union {
562 R m_r;
563 char const * m_msg;
564 };
565
566 constexpr /*explicit*/ checked_result(const R & r) :
567 m_e(safe_numerics_error::success),
568 m_r(r)
569 {}
570 constexpr /*explicit*/ checked_result(
571 safe_numerics_error e,
572 const char * msg = ""
573 ) :
574 m_e(e),
575 m_msg(msg)
576 {
577 assert(m_e != safe_numerics_error::success);
578 }
579 constexpr bool exception() const {
580 return m_e != safe_numerics_error::success;
581 }
582
583 // don't permit construction without initial value;
584 checked_result() = delete;
585
586 // disallow assignment
587 checked_result & operator=(const checked_result &) = delete;
588 };
589
590 // all arithmetic operations of type T are supported on checked_result<T>.
591 // but the results might surprising. For example
592
593
594 constexpr signed int test_constexpr(
595 const checked_result<signed int> & t,
596 const checked_result<signed int> & u
597 ){
598 const boost::logic::tribool tb2 = t < u;
599 const signed int x = (tb2) ? 2 : 3;
600 return x;
601 }
602
603 using namespace boost::safe_numerics;
604
605 int main()
606 {
607 constexpr const checked_result<signed int> po = safe_numerics_error::positive_overflow_error;
608 constexpr const checked_result<signed int> no = safe_numerics_error::negative_overflow_error;
609 constexpr const boost::logic::tribool tb = no < po;
610 const boost::logic::tribool tb1 = no > po;
611 constexpr const checked_result<signed int> re = safe_numerics_error::range_error;
612 const boost::logic::tribool tb2 = no < re;
613 const checked_result<signed int> x = no < re ? no : re;
614
615 static_assert(test_constexpr(no, re) == 3, "test_constexpr(no, re)");
616
617
618 static_assert(tb, "no < po");
619
620 signed int result;
621 if(tb)
622 result = 0;
623 else
624 result = 1;
625 std::cout << result;
626 return result;
627 }
628
629 #endif
630
631 #if 0
632
633 #include <boost/logic/tribool.hpp>
634 #include <cassert>
635 int main(){
636 constexpr const boost::tribool tb_t{true};
637 static_assert(tb_t, "tb_t");
638 assert(static_cast<bool>(tb_t));
639 constexpr boost::tribool tb_f{false};
640 static_assert(! tb_f, "tb_f");
641 assert(! static_cast<bool>(tb_f));
642 return 0;
643 }
644 #endif
645
646 #if 0
647 #include <boost/integer.hpp>
648 #include <boost/safe_numerics/utility.hpp>
649
650 // include headers to support safe integers
651 #include <boost/safe_numerics/cpp.hpp>
652 //#include <boost/safe_numerics/exception.hpp>
653
654 using promotion_policy = boost::safe_numerics::cpp<
655 8, // char 8 bits
656 16, // short 16 bits
657 16, // int 16 bits
658 16, // long 32 bits
659 32 // long long 32 bits
660 >;
661
662 template<typename R, typename T, typename U>
663 struct test {
664 using ResultType = promotion_policy::result_type<T,U>;
665 //boost::safe_numerics::utility::print_type<ResultType> pt;
666 static_assert(
667 std::is_same<R, ResultType>::value,
668 "is_same<R, ResultType>"
669 );
670 };
671
672 test<std::uint16_t, std::uint8_t, std::uint8_t> t1;
673
674 int main(){
675 return 0;
676 }
677
678 #endif
679
680 #if 0
681 #include <string>
682 #include <unordered_map>
683 #include <boost/safe_numerics/safe_integer.hpp>
684
685 #include <functional> // hash
686
687 template<typename T>
688 struct safe_hash {
689 size_t operator()(boost::safe_numerics::safe<T> const& t) const {
690 return std::hash<T>()(t);
691 }
692 };
693
694 int main(){
695 auto foo = std::unordered_map<
696 boost::safe_numerics::safe<int>,
697 std::string,
698 safe_hash<int>
699 >{};
700 foo[boost::safe_numerics::safe<int>(42)] = "hello, world!";
701 foo[42] = "hello, world!";
702 }
703
704 #endif
705
706 #if 0
707
708 #include <string>
709 #include <unordered_map>
710 #include <boost/safe_numerics/safe_integer.hpp>
711
712 #include <functional> // hash
713
714 template<typename T>
715 struct safe_hash {
716 size_t operator()(boost::safe_numerics::safe<T> const& t) const {
717 return std::hash<T>()(t);
718 }
719 };
720
721 int main(){
722 auto foo = std::unordered_map<int, std::string>{};
723 foo[boost::safe_numerics::safe<int>(42)] = "hello, world!";
724 }
725
726 #endif
727
728 #if 0
729
730 #include <iostream>
731 #include <boost/safe_numerics/safe_integer.hpp>
732 //#include <boost/safe_numerics/automatic.hpp>
733
734 using namespace boost::safe_numerics;
735
736 int main(){
737 using safe_int = safe<
738 int,
739 automatic,
740 loose_trap_policy
741 >;
742 safe_int i;
743 std::cin >> i; // might throw exception
744 auto j = i * i;
745 // won't ever trap
746 // result type can hold the maximum value of i * i
747 static_assert(is_safe<decltype(j)>::value, "result is a safe type");
748 static_assert(
749 std::numeric_limits<decltype(i * i)>::max() >=
750 std::numeric_limits<safe_int>::max() * std::numeric_limits<safe_int>::max(),
751 "result can never overflow"
752 ); // always true
753
754 return 0;
755 }
756
757 #include <cstdint>
758 #include <boost/safe_numerics/safe_integer_range.hpp>
759 #include <boost/safe_numerics/safe_integer_literal.hpp>
760
761 template <uintmax_t Min, uintmax_t Max>
762 using urange = boost::safe_numerics::safe_unsigned_range<
763 Min,
764 Max,
765 boost::safe_numerics::native,
766 boost::safe_numerics::strict_trap_policy
767 >;
768
769 template <uintmax_t N>
770 using ulit = boost::safe_numerics::safe_unsigned_literal<
771 N,
772 boost::safe_numerics::native,
773 boost::safe_numerics::strict_trap_policy
774 >;
775
776 int main(){
777 urange<0,4095> x = ulit<0>(); // 12 bits
778 urange<0, 69615> y = x * ulit<17>(); // no error - resulting value
779 // cannot exceed 69615
780 auto z = y / ulit<17>() ; //Boom, compile-time error
781 return z;
782 }
783
784 #endif
785
786 #if 0
787 #include <boost/safe_numerics/safe_integer_range.hpp>
788
789 int main(){
790 using namespace boost::safe_numerics;
791 safe_unsigned_range<0, 36> a = 30;
792 return 0;
793 }
794
795 #endif
796
797 #if 0
798 #include <iostream>
799 #include <functional>
800 #include <boost/safe_numerics/safe_integer_range.hpp>
801 #include <boost/safe_numerics/interval.hpp> // print variable range
802 #include <boost/safe_numerics/native.hpp> // native promotion policy
803 #include <boost/safe_numerics/exception.hpp> // safe_numerics_error
804 #include <boost/safe_numerics/exception_policies.hpp>
805
806 // log an exception condition but continue processing as though nothing has happened
807 // this would emulate the behavior of an unsafe type.
808 struct log_runtime_exception {
809 log_runtime_exception() = default;
810 void operator () (
811 const boost::safe_numerics::safe_numerics_error & e,
812 const char * message
813 ){
814 std::cout
815 << "Caught system_error with code "
816 << boost::safe_numerics::literal_string(e)
817 << " and message " << message << '\n';
818 }
819 };
820
821 // logging policy
822 // log arithmetic errors but ignore them and continue to execute
823 // implementation defined and undefined behavior is just executed
824 // without logging.
825
826 using logging_exception_policy = boost::safe_numerics::exception_policy<
827 log_runtime_exception, // arithmetic error
828 log_runtime_exception, // implementation defined behavior
829 log_runtime_exception, // undefined behavior
830 log_runtime_exception // uninitialized value
831 >;
832
833 template<unsigned int Min, unsigned int Max>
834 using sur = boost::safe_numerics::safe_unsigned_range<
835 Min, // min value in range
836 Max, // max value in range
837 boost::safe_numerics::native, // promotion policy
838 logging_exception_policy // exception policy
839 >;
840
841 template<int Min, int Max>
842 using ssr = boost::safe_numerics::safe_signed_range<
843 Min, // min value in range
844 Max, // max value in range
845 boost::safe_numerics::native, // promotion policy
846 logging_exception_policy // exception policy
847 >;
848
849 int main() {
850 const sur<1910, 2099> test0 = 7; // note logged exception - value undefined
851 std::cout << "test0 = " << test0 << '\n';
852 const ssr<1910, 2099> test1 = 7; // note logged exception - value undefined
853 std::cout << "test1 = " << test1 << '\n';
854 const sur<0, 2> test2 = 7; // note logged exception - value undefined
855 std::cout << "test2 = " << test2 << '\n';
856 const sur<1910, 2099> test3; // unitialized value
857 std::cout << "test3 = " << test3 << '\n';
858 sur<1910, 2099> test4 = 2000; // OK value
859 std::cout << "test4 = " << test4 << boost::safe_numerics::make_interval(test4) << '\n';
860 return 0;
861 }
862
863 #endif
864
865 #if 0
866 #include <iostream>
867 #include <boost/safe_numerics/safe_integer.hpp>
868
869 using boost::safe_numerics::safe;
870
871 int main(){
872 safe<safe<int>> r {};
873 //safe<int> r {};
874 std::cout << r << std::endl;
875 return 0;
876 }
877
878 #endif
879
880 #include <iostream>
881 #include <sstream>
882 #include <boost/safe_numerics/safe_integer.hpp>
883
884 int main(){
885 try {
886 boost::safe_numerics::safe<unsigned> u;
887 std::istringstream is{"-1"};
888 is >> u;
889 std::cout << u << std::endl;
890 }
891 catch (std::exception const& e)
892 {
893 std::cerr << "ERR: " << e.what() << std::endl;
894 }
895 return 0;
896 }