1 // Copyright (c) 2014 Thomas Heller 2 // Copyright (c) 2007-2017 Hartmut Kaiser 3 // Copyright (c) 2007 Richard D. Guidry Jr. 4 // 5 // Distributed under the Boost Software License, Version 1.0. (See accompanying 6 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 7 8 #if !defined(HPX_PARCELSET_LOCALITY_HPP) 9 #define HPX_PARCELSET_LOCALITY_HPP 10 11 #include <hpx/config.hpp> 12 13 #include <hpx/exception.hpp> 14 #include <hpx/runtime/parcelset_fwd.hpp> 15 #include <hpx/runtime/serialization/serialization_fwd.hpp> 16 #include <hpx/runtime/serialization/map.hpp> 17 #include <hpx/traits/is_iterator.hpp> 18 #include <hpx/util/assert.hpp> 19 20 #include <map> 21 #include <memory> 22 #include <string> 23 #include <type_traits> 24 #include <utility> 25 26 #include <hpx/config/warnings_prefix.hpp> 27 28 /////////////////////////////////////////////////////////////////////////////// 29 namespace hpx { namespace parcelset 30 { 31 class HPX_EXPORT locality 32 { 33 template <typename Impl> 34 class impl; 35 36 class impl_base 37 { 38 public: ~impl_base()39 virtual ~impl_base() {} 40 41 virtual bool equal(impl_base const & rhs) const = 0; 42 virtual bool less_than(impl_base const & rhs) const = 0; 43 virtual bool valid() const = 0; 44 virtual const char *type() const = 0; 45 virtual std::ostream & print(std::ostream & os) const = 0; 46 virtual void save(serialization::output_archive & ar) const = 0; 47 virtual void load(serialization::input_archive & ar) = 0; 48 virtual impl_base * clone() const = 0; 49 virtual impl_base * move() = 0; 50 51 template <typename Impl> get()52 Impl & get() 53 { 54 HPX_ASSERT(Impl::type() == type()); 55 return static_cast<impl<Impl>*>(this)->impl_; 56 } 57 58 template <typename Impl> get() const59 Impl const & get() const 60 { 61 HPX_ASSERT(Impl::type() == type()); 62 return static_cast<const impl<Impl>*>(this)->impl_; 63 } 64 }; 65 66 public: locality()67 locality() 68 {} 69 70 template <typename Impl, typename Enable = 71 typename std::enable_if< 72 !std::is_same<locality, typename util::decay<Impl>::type>::value && 73 !traits::is_iterator<Impl>::value 74 >::type 75 > locality(Impl && i)76 locality(Impl && i) 77 : impl_(new impl<typename util::decay<Impl>::type>(std::forward<Impl>(i))) 78 {} 79 locality(locality const & other)80 locality(locality const & other) 81 : impl_(other.impl_ ? other.impl_->clone() : nullptr) 82 { 83 } 84 locality(locality && other)85 locality(locality && other) 86 : impl_(other.impl_ ? other.impl_->move() : nullptr) 87 { 88 } 89 operator =(locality const & other)90 locality & operator=(locality const & other) 91 { 92 if(this != &other) 93 { 94 if(other.impl_) 95 { 96 impl_.reset(other.impl_->clone()); 97 } 98 else 99 { 100 impl_.reset(); 101 } 102 } 103 return *this; 104 } 105 operator =(locality && other)106 locality & operator=(locality && other) 107 { 108 if(this != &other) 109 { 110 if(other.impl_) 111 { 112 impl_.reset(other.impl_->move()); 113 } 114 else 115 { 116 impl_.reset(); 117 } 118 } 119 return *this; 120 } 121 122 /////////////////////////////////////////////////////////////////////// operator bool() const123 explicit operator bool() const noexcept 124 { 125 return impl_ ? impl_->valid(): false; 126 } 127 type() const128 const char *type() const 129 { 130 return impl_ ? impl_->type() : ""; 131 } 132 133 template <typename Impl> get()134 Impl & get() 135 { 136 HPX_ASSERT(impl_); 137 return impl_->get<Impl>(); 138 } 139 140 template <typename Impl> get() const141 Impl const & get() const 142 { 143 HPX_ASSERT(impl_); 144 return impl_->get<Impl>(); 145 } 146 147 private: operator ==(locality const & lhs,locality const & rhs)148 friend bool operator==(locality const& lhs, locality const& rhs) 149 { 150 if(lhs.impl_ == rhs.impl_) return true; 151 if(!lhs.impl_ || !rhs.impl_) return false; 152 return lhs.impl_->equal(*rhs.impl_); 153 } 154 operator !=(locality const & lhs,locality const & rhs)155 friend bool operator!=(locality const& lhs, locality const& rhs) 156 { 157 return !(lhs == rhs); 158 } 159 operator <(locality const & lhs,locality const & rhs)160 friend bool operator< (locality const& lhs, locality const& rhs) 161 { 162 if(lhs.impl_ == rhs.impl_) return false; 163 if(!lhs.impl_ || ! rhs.impl_) return false; 164 return lhs.impl_->less_than(*rhs.impl_); 165 } 166 operator >(locality const & lhs,locality const & rhs)167 friend bool operator> (locality const& lhs, locality const& rhs) 168 { 169 if(lhs.impl_ == rhs.impl_) return false; 170 if(!lhs.impl_ || ! rhs.impl_) return false; 171 return !(lhs < rhs) && !(lhs == rhs); 172 } 173 operator <<(std::ostream & os,locality const & l)174 friend std::ostream& operator<< (std::ostream& os, locality const& l) 175 { 176 if(!l.impl_) return os; 177 return l.impl_->print(os); 178 } 179 180 // serialization support 181 friend class hpx::serialization::access; 182 183 void save(serialization::output_archive& ar, const unsigned int version) const; 184 185 void load(serialization::input_archive& ar, const unsigned int version); 186 187 HPX_SERIALIZATION_SPLIT_MEMBER(); 188 189 std::unique_ptr<impl_base> impl_; 190 191 template <typename Impl> 192 class impl : public impl_base 193 { 194 public: impl(Impl && i)195 explicit impl(Impl && i) : impl_(std::move(i)) {} impl(Impl const & i)196 explicit impl(Impl const & i) : impl_(i) {} 197 equal(impl_base const & rhs) const198 bool equal(impl_base const & rhs) const 199 { 200 if(type() != rhs.type()) return false; 201 return impl_ == rhs.get<Impl>(); 202 } 203 less_than(impl_base const & rhs) const204 bool less_than(impl_base const & rhs) const 205 { 206 return type() < rhs.type() || 207 (type() == rhs.type() && impl_ < rhs.get<Impl>()); 208 } 209 valid() const210 bool valid() const 211 { 212 return !!impl_; 213 } 214 type() const215 const char *type() const 216 { 217 return Impl::type(); 218 } 219 print(std::ostream & os) const220 std::ostream & print(std::ostream & os) const 221 { 222 os << impl_; 223 return os; 224 } 225 save(serialization::output_archive & ar) const226 void save(serialization::output_archive & ar) const 227 { 228 impl_.save(ar); 229 } 230 load(serialization::input_archive & ar)231 void load(serialization::input_archive & ar) 232 { 233 impl_.load(ar); 234 } 235 clone() const236 impl_base * clone() const 237 { 238 return new impl<Impl>(impl_); 239 } 240 move()241 impl_base * move() 242 { 243 return new impl<Impl>(std::move(impl_)); 244 } 245 246 Impl impl_; 247 }; 248 }; 249 250 typedef std::map<std::string, locality> endpoints_type; 251 252 std::ostream& operator<< (std::ostream& os, endpoints_type const& endpoints); 253 }} 254 255 #include <hpx/config/warnings_suffix.hpp> 256 257 #endif 258