1 /*-----------------------------------------------------------------------------+
2 Copyright (c) 2007-2009: 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_SEPARATE_INTERVAL_SET_HPP_JOFA_080608
9 #define BOOST_ICL_SEPARATE_INTERVAL_SET_HPP_JOFA_080608
10 
11 #include <boost/assert.hpp>
12 #include <boost/icl/type_traits/is_interval_separator.hpp>
13 #include <boost/icl/interval_base_set.hpp>
14 #include <boost/icl/interval_set.hpp>
15 
16 namespace boost{namespace icl
17 {
18 
19 /** \brief Implements a set as a set of intervals - leaving adjoining intervals separate */
20 template
21 <
22     typename                         DomainT,
23     ICL_COMPARE                      Compare  = ICL_COMPARE_INSTANCE(ICL_COMPARE_DEFAULT, DomainT),
24     ICL_INTERVAL(ICL_COMPARE) Interval = ICL_INTERVAL_INSTANCE(ICL_INTERVAL_DEFAULT, DomainT, Compare),
25     ICL_ALLOC                        Alloc    = std::allocator
26 >
27 class separate_interval_set:
28     public interval_base_set<separate_interval_set<DomainT,Compare,Interval,Alloc>,
29                              DomainT,Compare,Interval,Alloc>
30 {
31 public:
32     typedef separate_interval_set<DomainT,Compare,Interval,Alloc> type;
33 
34     typedef interval_base_set<type,DomainT,Compare,Interval,Alloc> base_type;
35 
36     typedef type overloadable_type;
37     typedef type key_object_type;
38 
39     typedef interval_set<DomainT,Compare,Interval,Alloc> joint_type;
40 
41     /// The domain type of the set
42     typedef DomainT   domain_type;
43     /// The codomaintype is the same as domain_type
44     typedef DomainT   codomain_type;
45 
46     /// The element type of the set
47     typedef DomainT   element_type;
48     /// The interval type of the set
49     typedef ICL_INTERVAL_TYPE(Interval,DomainT,Compare) interval_type;
50     /// The segment type of the set
51     typedef interval_type   segment_type;
52 
53     /// Comparison functor for domain values
54     typedef ICL_COMPARE_DOMAIN(Compare,DomainT) domain_compare;
55     /// Comparison functor for intervals
56     typedef exclusive_less_than<interval_type> interval_compare;
57 
58     /// Comparison functor for keys
59     typedef exclusive_less_than<interval_type> key_compare;
60 
61     /// The allocator type of the set
62     typedef Alloc<interval_type> allocator_type;
63 
64     /// allocator type of the corresponding element set
65     typedef Alloc<DomainT> domain_allocator_type;
66 
67     /// The corresponding atomized type representing this interval container of elements
68     typedef typename base_type::atomized_type atomized_type;
69 
70     /// Container type for the implementation
71     typedef typename base_type::ImplSetT ImplSetT;
72 
73     /// key type of the implementing container
74     typedef typename ImplSetT::key_type   key_type;
75     /// data type of the implementing container
76     typedef typename ImplSetT::value_type data_type;
77     /// value type of the implementing container
78     typedef typename ImplSetT::value_type value_type;
79 
80     /// iterator for iteration over intervals
81     typedef typename ImplSetT::iterator iterator;
82     /// const_iterator for iteration over intervals
83     typedef typename ImplSetT::const_iterator const_iterator;
84 
85 
86     enum { fineness = 2 };
87 
88 public:
89     //==========================================================================
90     //= Construct, copy, destruct
91     //==========================================================================
92     /// Default constructor for the empty object
separate_interval_set()93     separate_interval_set(): base_type() {}
94     /// Copy constructor
separate_interval_set(const separate_interval_set & src)95     separate_interval_set(const separate_interval_set& src): base_type(src) {}
96 
97     /// Copy constructor for base_type
98     template<class SubType>
separate_interval_set(const interval_base_set<SubType,DomainT,Compare,Interval,Alloc> & src)99     separate_interval_set
100         (const interval_base_set<SubType,DomainT,Compare,Interval,Alloc>& src)
101     {
102         this->assign(src);
103     }
104 
105     /// Constructor for a single element
separate_interval_set(const domain_type & elem)106     explicit separate_interval_set(const domain_type& elem): base_type() { this->add(elem); }
107     /// Constructor for a single interval
separate_interval_set(const interval_type & itv)108     explicit separate_interval_set(const interval_type& itv): base_type() { this->add(itv); }
109 
110     /// Assignment operator
111     template<class SubType>
operator =(const interval_base_set<SubType,DomainT,Compare,Interval,Alloc> & src)112     separate_interval_set& operator =
113         (const interval_base_set<SubType,DomainT,Compare,Interval,Alloc>& src)
114     {
115         this->assign(src);
116         return *this;
117     }
118 
119     /// Assignment from a base interval_set.
120     template<class SubType>
assign(const interval_base_set<SubType,DomainT,Compare,Interval,Alloc> & src)121     void assign(const interval_base_set<SubType,DomainT,Compare,Interval,Alloc>& src)
122     {
123         this->clear();
124         this->_set.insert(src.begin(), src.end());
125     }
126 
127 
128 private:
129     // Private functions that shall be accessible by the baseclass:
130     friend class
131         interval_base_set<separate_interval_set<DomainT,Compare,Interval,Alloc>,
132                                                 DomainT,Compare,Interval,Alloc>;
133 
handle_inserted(iterator inserted_)134     iterator handle_inserted(iterator inserted_)
135     {
136         return inserted_;
137     }
138 
add_over(const interval_type & addend,iterator last_)139     iterator add_over(const interval_type& addend, iterator last_)
140     {
141         return segmental::join_under(*this, addend, last_);
142     }
143 
add_over(const interval_type & addend)144     iterator add_over(const interval_type& addend)
145     {
146         return segmental::join_under(*this, addend);
147     }
148 
149 } ;
150 
151 
152 
153 //-----------------------------------------------------------------------------
154 // type traits
155 //-----------------------------------------------------------------------------
156 template <class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc>
157 struct is_set<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> >
158 {
159     typedef is_set<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> > type;
160     BOOST_STATIC_CONSTANT(bool, value = true);
161 };
162 
163 template <class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc>
164 struct is_interval_container<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> >
165 {
166     typedef is_interval_container<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> > type;
167     BOOST_STATIC_CONSTANT(bool, value = true);
168 };
169 
170 template <class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc>
171 struct is_interval_separator<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> >
172 {
173     typedef is_interval_separator<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> > type;
174     BOOST_STATIC_CONSTANT(bool, value = true);
175 };
176 
177 //-----------------------------------------------------------------------------
178 // type representation
179 //-----------------------------------------------------------------------------
180 template <class DomainT, ICL_COMPARE Compare, ICL_INTERVAL(ICL_COMPARE)  Interval, ICL_ALLOC Alloc>
181 struct type_to_string<icl::separate_interval_set<DomainT,Compare,Interval,Alloc> >
182 {
applyboost::icl::type_to_string183     static std::string apply()
184     { return "se_itv_set<"+ type_to_string<DomainT>::apply() +">"; }
185 };
186 
187 }} // namespace icl boost
188 
189 #endif
190 
191 
192