Use the attribute enums to query if a function has an attribute.
[oota-llvm.git] / include / llvm / Support / Endian.h
index c98e2dc66cc16671aba39c973e571844c2d89796..8d5649dc1f91ec3ab130d168b1a1422d81daef02 100644 (file)
@@ -14,8 +14,8 @@
 #ifndef LLVM_SUPPORT_ENDIAN_H
 #define LLVM_SUPPORT_ENDIAN_H
 
-#include "llvm/Config/config.h"
-#include "llvm/System/SwapByteOrder.h"
+#include "llvm/Support/Host.h"
+#include "llvm/Support/SwapByteOrder.h"
 #include "llvm/Support/type_traits.h"
 
 namespace llvm {
@@ -24,19 +24,6 @@ namespace support {
 enum endianness {big, little};
 enum alignment {unaligned, aligned};
 
-template<typename value_type, int host, int target>
-static typename enable_if_c<host == target, value_type>::type
-SwapByteOrderIfDifferent(value_type value) {
-  // Target endianess is the same as the host. Just pass the value through.
-  return value;
-}
-
-template<typename value_type, int host, int target>
-static typename enable_if_c<host != target, value_type>::type
-SwapByteOrderIfDifferent(value_type value) {
-    return sys::SwapByteOrder<value_type>(value);
-}
-
 namespace detail {
 
 template<typename value_type, alignment align>
@@ -60,52 +47,49 @@ struct alignment_access_helper<value_type, unaligned>
 
 } // end namespace detail
 
-#if defined(LLVM_IS_HOST_BIG_ENDIAN) \
- || defined(_BIG_ENDIAN) || defined(__BIG_ENDIAN__)
-static const endianness host_endianness = big;
-#else
-static const endianness host_endianness = little;
-#endif
-
-struct endian {
+namespace endian {
   template<typename value_type, alignment align>
-  static value_type read_le(const void *memory) {
-    return SwapByteOrderIfDifferent<value_type, host_endianness, little>(
+  inline value_type read_le(const void *memory) {
+    value_type t =
       reinterpret_cast<const detail::alignment_access_helper
-        <value_type, align> *>(memory)->val);
+        <value_type, align> *>(memory)->val;
+    if (sys::isBigEndianHost())
+      return sys::SwapByteOrder(t);
+    return t;
   }
 
   template<typename value_type, alignment align>
-  static void write_le(void *memory, value_type value) {
+  inline void write_le(void *memory, value_type value) {
+    if (sys::isBigEndianHost())
+      value = sys::SwapByteOrder(value);
     reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
-      (memory)->val =
-        SwapByteOrderIfDifferent< value_type
-                                , host_endianness
-                                , little>(value);
+      (memory)->val = value;
   }
 
   template<typename value_type, alignment align>
-  static value_type read_be(const void *memory) {
-    return SwapByteOrderIfDifferent<value_type, host_endianness, big>(
+  inline value_type read_be(const void *memory) {
+    value_type t =
       reinterpret_cast<const detail::alignment_access_helper
-        <value_type, align> *>(memory)->val);
+        <value_type, align> *>(memory)->val;
+    if (sys::isLittleEndianHost())
+      return sys::SwapByteOrder(t);
+    return t;
   }
 
   template<typename value_type, alignment align>
-  static void write_be(void *memory, value_type value) {
-    reinterpret_cast<detail::alignment_access_helper
-      <value_type, align> *>(memory)->val =
-        SwapByteOrderIfDifferent< value_type
-                                , host_endianness
-                                , big>(value);
+  inline void write_be(void *memory, value_type value) {
+    if (sys::isLittleEndianHost())
+      value = sys::SwapByteOrder(value);
+    reinterpret_cast<detail::alignment_access_helper<value_type, align> *>
+      (memory)->val = value;
   }
-};
+}
 
 namespace detail {
 
 template<typename value_type,
-         endianness target_endianness,
-         alignment target_alignment>
+         endianness endian,
+         alignment  align>
 class packed_endian_specific_integral;
 
 template<typename value_type>
@@ -114,6 +98,9 @@ public:
   operator value_type() const {
     return endian::read_le<value_type, unaligned>(Value);
   }
+  void operator=(value_type newValue) {
+    endian::write_le<value_type, unaligned>((void *)&Value, newValue);
+  }
 private:
   uint8_t Value[sizeof(value_type)];
 };
@@ -124,6 +111,9 @@ public:
   operator value_type() const {
     return endian::read_be<value_type, unaligned>(Value);
   }
+  void operator=(value_type newValue) {
+    endian::write_be<value_type, unaligned>((void *)&Value, newValue);
+  }
 private:
   uint8_t Value[sizeof(value_type)];
 };
@@ -134,6 +124,9 @@ public:
   operator value_type() const {
     return endian::read_le<value_type, aligned>(&Value);
   }
+  void operator=(value_type newValue) {
+    endian::write_le<value_type, aligned>((void *)&Value, newValue);
+  }
 private:
   value_type Value;
 };
@@ -144,6 +137,9 @@ public:
   operator value_type() const {
     return endian::read_be<value_type, aligned>(&Value);
   }
+  void operator=(value_type newValue) {
+    endian::write_be<value_type, aligned>((void *)&Value, newValue);
+  }
 private:
   value_type Value;
 };