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