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_INTERVAL_HPP_JOFA_101014
9 #define BOOST_ICL_INTERVAL_HPP_JOFA_101014
10 
11 
12 #include <boost/icl/type_traits/interval_type_default.hpp>
13 
14 
15 namespace boost{ namespace icl
16 {
17 
18     template <class IntervalT, bool IsDiscrete, bound_type PretendedBounds, bound_type RepresentedBounds>
19     struct static_interval;
20 
21     template <class DomainT, ICL_COMPARE Compare = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT)>
22     struct interval
23     {
24         typedef typename interval_type_default<DomainT,Compare>::type interval_type;
25         typedef interval_type type;
26 
27 #ifdef BOOST_ICL_USE_STATIC_BOUNDED_INTERVALS
28 
openboost::icl::interval29         static inline interval_type open(const DomainT& low, const DomainT& up)
30         {
31             return
32                 static_interval
33                 < interval_type                // if the domain_type is discrete ...
34                 , is_discrete<typename interval_traits<interval_type>::domain_type>::value
35                 , interval_bounds::static_open // 'pretended' bounds will be transformed to
36                 , interval_bound_type<interval_type>::value // the represented bounds
37                 >
38                 ::construct(low, up);
39         }
40 
left_openboost::icl::interval41         static inline interval_type left_open(const DomainT& low, const DomainT& up)
42         {
43             return
44                 static_interval
45                 < interval_type
46                 , is_discrete<typename interval_traits<interval_type>::domain_type>::value
47                 , interval_bounds::static_left_open
48                 , interval_bound_type<interval_type>::value
49                 >
50                 ::construct(low, up);
51         }
52 
right_openboost::icl::interval53         static inline interval_type right_open(const DomainT& low, const DomainT& up)
54         {
55             return
56                 static_interval
57                 < interval_type
58                 , is_discrete<typename interval_traits<interval_type>::domain_type>::value
59                 , interval_bounds::static_right_open
60                 , interval_bound_type<interval_type>::value
61                 >
62                 ::construct(low, up);
63         }
64 
closedboost::icl::interval65         static inline interval_type closed(const DomainT& low, const DomainT& up)
66         {
67             return
68                 static_interval
69                 < interval_type
70                 , is_discrete<typename interval_traits<interval_type>::domain_type>::value
71                 , interval_bounds::static_closed
72                 , interval_bound_type<interval_type>::value
73                 >
74                 ::construct(low, up);
75         }
76 
constructboost::icl::interval77         static inline interval_type construct(const DomainT& low, const DomainT& up)
78         { return icl::construct<interval_type>(low, up); }
79 
80 #else // ICL_USE_DYNAMIC_INTERVAL_BORDER_DEFAULTS
right_openboost::icl::interval81         static inline interval_type right_open(const DomainT& low, const DomainT& up)
82         { return icl::construct<interval_type>(low, up, interval_bounds::right_open()); }
83 
left_openboost::icl::interval84         static inline interval_type left_open(const DomainT& low, const DomainT& up)
85         { return icl::construct<interval_type>(low, up, interval_bounds::left_open()); }
86 
openboost::icl::interval87         static inline interval_type open(const DomainT& low, const DomainT& up)
88         { return icl::construct<interval_type>(low, up, interval_bounds::open()); }
89 
closedboost::icl::interval90         static inline interval_type closed(const DomainT& low, const DomainT& up)
91         { return icl::construct<interval_type>(low, up, interval_bounds::closed()); }
92 
constructboost::icl::interval93         static inline interval_type construct(const DomainT& low, const DomainT& up)
94         { return icl::construct<interval_type>(low, up); }
95 
96 #endif
97     };
98 
99     template <class IntervalT, bound_type PretendedBounds, bound_type RepresentedBounds>
100     struct static_interval<IntervalT, true, PretendedBounds, RepresentedBounds>
101     {// is_discrete<domain_type<IntervalT>>
102         typedef typename interval_traits<IntervalT>::domain_type domain_type;
103 
constructboost::icl::static_interval104         static inline IntervalT construct(const domain_type& low, const domain_type& up)
105         {
106             return icl::construct<IntervalT>(
107                   shift_lower(interval_bounds(PretendedBounds), interval_bounds(RepresentedBounds), low)
108                 , shift_upper(interval_bounds(PretendedBounds), interval_bounds(RepresentedBounds), up )
109                 );
110         }
111     };
112 
113     template <class IntervalT, bound_type PretendedBounds, bound_type RepresentedBounds>
114     struct static_interval<IntervalT, false, PretendedBounds, RepresentedBounds>
115     {// !is_discrete<domain_type<IntervalT>>
116         typedef typename interval_traits<IntervalT>::domain_type domain_type;
117 
constructboost::icl::static_interval118         static inline IntervalT construct(const domain_type& low, const domain_type& up)
119         {
120             BOOST_STATIC_ASSERT((is_discrete<domain_type>::value || PretendedBounds==RepresentedBounds));
121             // For domain_types that are not discrete, e.g. interval<float>
122             // one of the following must hold: If you call
123             // interval<T>::right_open(x,y) then interval<T>::type must be static_right_open
124             // interval<T>::left_open(x,y)  then interval<T>::type must be static_left_open
125             // interval<T>::open(x,y)       then interval<T>::type must be static_open
126             // interval<T>::closed(x,y)     then interval<T>::type must be static_closed
127             // Conversion between 'PretendedBounds' and 'RepresentedBounds' is only possible
128             // for discrete domain_types.
129             return icl::construct<IntervalT>(low, up);
130         }
131     };
132 
133 }} // namespace boost icl
134 
135 #endif // BOOST_ICL_INTERVAL_HPP_JOFA_101014
136 
137