Chris@16
|
1 /*-----------------------------------------------------------------------------+
|
Chris@16
|
2 Copyright (c) 2010-2010: Joachim Faulhaber
|
Chris@16
|
3 +------------------------------------------------------------------------------+
|
Chris@16
|
4 Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
5 (See accompanying file LICENCE.txt or copy at
|
Chris@16
|
6 http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
7 +-----------------------------------------------------------------------------*/
|
Chris@16
|
8 #ifndef BOOST_ICL_CONCEPT_INTERVAL_BOUNDS_HPP_JOFA_100927
|
Chris@16
|
9 #define BOOST_ICL_CONCEPT_INTERVAL_BOUNDS_HPP_JOFA_100927
|
Chris@16
|
10
|
Chris@16
|
11 #include <boost/icl/interval_bounds.hpp>
|
Chris@16
|
12 #include <boost/icl/type_traits/is_discrete.hpp>
|
Chris@16
|
13 #include <boost/icl/type_traits/is_numeric.hpp>
|
Chris@16
|
14
|
Chris@16
|
15 namespace boost{namespace icl
|
Chris@16
|
16 {
|
Chris@16
|
17
|
Chris@16
|
18 inline interval_bounds left(interval_bounds x1)
|
Chris@16
|
19 { return interval_bounds(x1._bits & interval_bounds::_left); }
|
Chris@16
|
20
|
Chris@16
|
21 inline interval_bounds right(interval_bounds x1)
|
Chris@16
|
22 { return interval_bounds(x1._bits & interval_bounds::_right); }
|
Chris@16
|
23
|
Chris@16
|
24 inline interval_bounds all(interval_bounds x1)
|
Chris@16
|
25 { return interval_bounds(x1._bits & interval_bounds::_all); }
|
Chris@16
|
26
|
Chris@16
|
27 inline bool operator == (const interval_bounds x1, const interval_bounds x2)
|
Chris@16
|
28 { return x1._bits == x2._bits; }
|
Chris@16
|
29
|
Chris@16
|
30 inline bool operator != (const interval_bounds x1, const interval_bounds x2)
|
Chris@16
|
31 { return x1._bits != x2._bits; }
|
Chris@16
|
32
|
Chris@16
|
33 inline interval_bounds operator & (interval_bounds x1, interval_bounds x2)
|
Chris@16
|
34 { return interval_bounds(x1._bits & x2._bits); }
|
Chris@16
|
35
|
Chris@16
|
36 inline interval_bounds operator | (interval_bounds x1, interval_bounds x2)
|
Chris@16
|
37 { return interval_bounds(x1._bits | x2._bits); }
|
Chris@16
|
38
|
Chris@16
|
39 // left shift (multiplies by 2^shift)
|
Chris@16
|
40 inline interval_bounds operator << (interval_bounds bounds, unsigned int shift)
|
Chris@16
|
41 { return interval_bounds(bounds._bits << shift); }
|
Chris@16
|
42
|
Chris@16
|
43 // right shift (divides by 2^shift)
|
Chris@16
|
44 inline interval_bounds operator >> (interval_bounds bounds, unsigned int shift)
|
Chris@16
|
45 { return interval_bounds(bounds._bits >> shift); }
|
Chris@16
|
46
|
Chris@16
|
47 inline interval_bounds operator ~ (interval_bounds x1)
|
Chris@16
|
48 { return all(interval_bounds(~(x1._bits))); }
|
Chris@16
|
49
|
Chris@16
|
50 inline interval_bounds outer_bounds(interval_bounds x1, interval_bounds x2)
|
Chris@16
|
51 { return left(x1) | right(x2); }
|
Chris@16
|
52
|
Chris@16
|
53 inline interval_bounds inner_bounds(interval_bounds x1, interval_bounds x2)
|
Chris@16
|
54 { return interval_bounds(x1.reverse_right() | x2.reverse_left()); }
|
Chris@16
|
55
|
Chris@16
|
56 inline interval_bounds left_bounds(interval_bounds x1, interval_bounds x2)
|
Chris@16
|
57 { return left(x1) | (left(x2) >> 1); }
|
Chris@16
|
58
|
Chris@16
|
59 inline interval_bounds right_bounds(interval_bounds x1, interval_bounds x2)
|
Chris@16
|
60 { return (right(x1) <<1 ) | right(x2); }
|
Chris@16
|
61
|
Chris@16
|
62 inline interval_bounds left_subtract_bounds(interval_bounds x1, interval_bounds x2)
|
Chris@16
|
63 { return right(x1) | ~(right(x2) << 1); }
|
Chris@16
|
64
|
Chris@16
|
65 inline interval_bounds right_subtract_bounds(interval_bounds x1, interval_bounds x2)
|
Chris@16
|
66 { return left(x1) | ~(left(x2) >> 1); }
|
Chris@16
|
67
|
Chris@16
|
68 inline bool is_complementary(interval_bounds x1)
|
Chris@16
|
69 { return x1 == interval_bounds::right_open() || x1 == interval_bounds::left_open(); }
|
Chris@16
|
70
|
Chris@16
|
71 inline bool is_left_closed(interval_bounds bounds)
|
Chris@16
|
72 { return bounds.left().bits()==2; }
|
Chris@16
|
73
|
Chris@16
|
74 inline bool is_right_closed(interval_bounds bounds)
|
Chris@16
|
75 { return bounds.right().bits()==1; }
|
Chris@16
|
76
|
Chris@16
|
77 inline std::string left_bracket(interval_bounds bounds)
|
Chris@16
|
78 { return is_left_closed(bounds) ? "[" : "("; }
|
Chris@16
|
79
|
Chris@16
|
80 inline std::string right_bracket(interval_bounds bounds)
|
Chris@16
|
81 { return is_right_closed(bounds) ? "]" : ")"; }
|
Chris@16
|
82
|
Chris@16
|
83 template <class Type>
|
Chris@16
|
84 inline typename enable_if<is_discrete<Type>, Type>::type
|
Chris@16
|
85 shift_lower(interval_bounds decl, interval_bounds repr, const Type& low)
|
Chris@16
|
86 {
|
Chris@16
|
87 if(is_left_closed(decl) && !is_left_closed(repr))
|
Chris@16
|
88 return icl::pred(low);
|
Chris@16
|
89 else if(!is_left_closed(decl) && is_left_closed(repr))
|
Chris@16
|
90 return icl::succ(low);
|
Chris@16
|
91 else
|
Chris@16
|
92 return low;
|
Chris@16
|
93 }
|
Chris@16
|
94
|
Chris@16
|
95 template <class Type>
|
Chris@16
|
96 inline typename enable_if<is_discrete<Type>, Type>::type
|
Chris@16
|
97 shift_upper(interval_bounds decl, interval_bounds repr, const Type& up)
|
Chris@16
|
98 {
|
Chris@16
|
99 if(!is_right_closed(decl) && is_right_closed(repr))
|
Chris@16
|
100 return icl::pred(up);
|
Chris@16
|
101 else if(is_right_closed(decl) && !is_right_closed(repr))
|
Chris@16
|
102 return icl::succ(up);
|
Chris@16
|
103 else
|
Chris@16
|
104 return up;
|
Chris@16
|
105 }
|
Chris@16
|
106
|
Chris@16
|
107 template<class CharType, class CharTraits>
|
Chris@16
|
108 std::basic_ostream<CharType, CharTraits>& operator <<
|
Chris@16
|
109 (std::basic_ostream<CharType, CharTraits> &stream,
|
Chris@16
|
110 interval_bounds const& object)
|
Chris@16
|
111 {
|
Chris@16
|
112 return stream << left_bracket(object) << right_bracket(object);
|
Chris@16
|
113 }
|
Chris@16
|
114
|
Chris@16
|
115
|
Chris@16
|
116
|
Chris@16
|
117 template<class IntervalT>
|
Chris@16
|
118 inline typename
|
Chris@16
|
119 boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
|
Chris@16
|
120 outer_bounds(const IntervalT& x1, const IntervalT& x2)
|
Chris@16
|
121 { return outer_bounds(x1.bounds(), x2.bounds()); }
|
Chris@16
|
122
|
Chris@16
|
123 template<class IntervalT>
|
Chris@16
|
124 inline typename
|
Chris@16
|
125 boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
|
Chris@16
|
126 inner_bounds(const IntervalT& x1, const IntervalT& x2)
|
Chris@16
|
127 { return inner_bounds(x1.bounds(), x2.bounds()); }
|
Chris@16
|
128
|
Chris@16
|
129 template<class IntervalT>
|
Chris@16
|
130 inline typename
|
Chris@16
|
131 boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
|
Chris@16
|
132 left_bounds(const IntervalT& x1, const IntervalT& x2)
|
Chris@16
|
133 { return left_bounds(x1.bounds(), x2.bounds()); }
|
Chris@16
|
134
|
Chris@16
|
135 template<class IntervalT>
|
Chris@16
|
136 inline typename
|
Chris@16
|
137 boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
|
Chris@16
|
138 right_bounds(const IntervalT& x1, const IntervalT& x2)
|
Chris@16
|
139 { return right_bounds(x1.bounds(), x2.bounds()); }
|
Chris@16
|
140
|
Chris@16
|
141 template<class IntervalT>
|
Chris@16
|
142 inline typename
|
Chris@16
|
143 boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
|
Chris@16
|
144 left_subtract_bounds(const IntervalT& x1, const IntervalT& x2)
|
Chris@16
|
145 { return left_subtract_bounds(x1.bounds(), x2.bounds()); }
|
Chris@16
|
146
|
Chris@16
|
147 template<class IntervalT>
|
Chris@16
|
148 inline typename
|
Chris@16
|
149 boost::enable_if<has_dynamic_bounds<IntervalT>, interval_bounds>::type
|
Chris@16
|
150 right_subtract_bounds(const IntervalT& x1, const IntervalT& x2)
|
Chris@16
|
151 { return right_subtract_bounds(x1.bounds(), x2.bounds()); }
|
Chris@16
|
152
|
Chris@16
|
153
|
Chris@16
|
154 }} // namespace icl boost
|
Chris@16
|
155
|
Chris@16
|
156 #endif
|
Chris@16
|
157
|