00001
00005 #ifndef CCTBX_MILLER_H
00006 #define CCTBX_MILLER_H
00007
00008 #include <scitbx/vec3.h>
00009 #include <scitbx/array_family/misc_functions.h>
00010 #include <cctbx/import_scitbx_af.h>
00011 #include <cctbx/error.h>
00012 #include <cstdio>
00013
00014 namespace cctbx {
00016 namespace miller {
00017
00019 template <typename NumType=int>
00020 class index : public scitbx::vec3<NumType>
00021 {
00022 public:
00023 typedef scitbx::vec3<NumType> base_type;
00024
00026 index() : base_type(0,0,0) {}
00027
00029 index(base_type const& h) : base_type(h) {}
00030
00032 template <typename OtherNumType>
00033 index(af::tiny_plain<OtherNumType, 3> const& v)
00034 {
00035 for(std::size_t i=0;i<3;i++) this->elems[i] = v[i];
00036 }
00037
00039 template <typename OtherNumType>
00040 explicit
00041 index(const OtherNumType* hkl)
00042 {
00043 for(std::size_t i=0;i<3;i++) this->elems[i] = hkl[i];
00044 }
00045
00047 index(NumType const& h, NumType const& k, NumType const& l)
00048 : base_type(h, k, l)
00049 {}
00050
00052
00055 bool operator<(index const& other) const
00056 {
00057 const int P[3] = {2, 0, 1};
00058 for(std::size_t i=0;i<3;i++) {
00059 if (this->elems[P[i]] >= 0 && other[P[i]] < 0) return true;
00060 if (this->elems[P[i]] < 0 && other[P[i]] >= 0) return false;
00061 }
00062 for(std::size_t i=0;i<3;i++) {
00063 if ( scitbx::fn::absolute(this->elems[P[i]])
00064 < scitbx::fn::absolute(other[P[i]])) return true;
00065 if ( scitbx::fn::absolute(this->elems[P[i]])
00066 > scitbx::fn::absolute(other[P[i]])) return false;
00067 }
00068 return false;
00069 }
00070
00072 bool operator>(index const& other) const
00073 {
00074 if (*this < other) return false;
00075 for(std::size_t i=0;i<3;i++) {
00076 if (this->elems[i] != other[i]) return true;
00077 }
00078 return false;
00079 }
00080
00081 #if defined(BOOST_MSVC) && BOOST_MSVC <= 1300 // VC++ 7.0
00082
00083 index operator-() const
00084 {
00085 return index(-static_cast<base_type>(*this));
00086 }
00087 #endif
00088
00089 #if defined(__GNUC__) \
00090 && __GNUC__ == 3 \
00091 && __GNUC_MINOR__ == 2 \
00092 && __GNUC_PATCHLEVEL__ != 0 // 3 known to fail, 0 OK, others unknown
00093
00094 bool operator!=(index const& other) const
00095 {
00096 return static_cast<base_type>(*this) != static_cast<base_type>(other);
00097 }
00098 #endif
00099
00100 std::string
00101 as_string() const
00102 {
00103 char buf[128];
00104 buf[127] = '\0';
00105 std::sprintf(buf, "(%ld,%ld,%ld)",
00106 static_cast<long>(this->elems[0]),
00107 static_cast<long>(this->elems[1]),
00108 static_cast<long>(this->elems[2]));
00109 CCTBX_ASSERT(buf[127] == '\0');
00110 return std::string(buf);
00111 }
00112 };
00113
00117 template <typename NumType=int>
00118 class fast_less_than
00119 {
00120 public:
00122 bool operator()(index<NumType> const& h1, index<NumType> const& h2) const
00123 {
00124 for(std::size_t i=0;i<3;i++) {
00125 if (h1[i] < h2[i]) return true;
00126 if (h1[i] > h2[i]) return false;
00127 }
00128 return false;
00129 }
00130 };
00131
00132 }}
00133
00134 #endif // CCTBX_MILLER_H