mfbt/Alignment.h
author Masayuki Nakano <masayuki@d-toybox.com>
Thu, 16 Mar 2017 16:26:43 +0900
changeset 398554 8e72178c3893c377972209cccd2e561e1ec06c7d
parent 393735 7e72aa400561c7767ca4734f23ff3903e55d4e0a
child 428008 06d2f579a7f39ee0b2f20f43ec7e570fded37872
permissions -rw-r--r--
Bug 1339331 TextEventDispatcher should replace \r in composition string with \n and TextComposition should allow to input \n with composition events r=m_kato According to ATOK's behavior, IME may send different line breaker from its platform's standard. Therefore, we should treat \r as \n too. Additionally, currently, TextComposition doesn't allow to input \n with composition. However, this was added for preventing to see odd control characters as boxes with code point. Therefore, we should allow \n for IMEs. (It was allowed, this limitation is unexpected when I reviewed the patch to reject control characters in TextComposition.) MozReview-Commit-ID: DzGSMgp89Av

/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

/* Functionality related to memory alignment. */

#ifndef mozilla_Alignment_h
#define mozilla_Alignment_h

#include "mozilla/Attributes.h"
#include <stddef.h>
#include <stdint.h>

namespace mozilla {

/*
 * This class, and the corresponding macro MOZ_ALIGNOF, figures out how many
 * bytes of alignment a given type needs.
 */
template<typename T>
class AlignmentFinder
{
  struct Aligner
  {
    char mChar;
    T mT;
  };

public:
  static const size_t alignment = sizeof(Aligner) - sizeof(T);
};

#define MOZ_ALIGNOF(T) mozilla::AlignmentFinder<T>::alignment

/*
 * Declare the MOZ_ALIGNED_DECL macro for declaring aligned types.
 *
 * For instance,
 *
 *   MOZ_ALIGNED_DECL(char arr[2], 8);
 *
 * will declare a two-character array |arr| aligned to 8 bytes.
 */

#if defined(__GNUC__)
#  define MOZ_ALIGNED_DECL(_type, _align) \
     _type __attribute__((aligned(_align)))
#elif defined(_MSC_VER)
#  define MOZ_ALIGNED_DECL(_type, _align) \
     __declspec(align(_align)) _type
#else
#  warning "We don't know how to align variables on this compiler."
#  define MOZ_ALIGNED_DECL(_type, _align) _type
#endif

/*
 * AlignedElem<N> is a structure whose alignment is guaranteed to be at least N
 * bytes.
 *
 * We support 1, 2, 4, 8, and 16-bit alignment.
 */
template<size_t Align>
struct AlignedElem;

/*
 * We have to specialize this template because GCC doesn't like
 * __attribute__((aligned(foo))) where foo is a template parameter.
 */

template<>
struct AlignedElem<1>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 1);
};

template<>
struct AlignedElem<2>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 2);
};

template<>
struct AlignedElem<4>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 4);
};

template<>
struct AlignedElem<8>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 8);
};

template<>
struct AlignedElem<16>
{
  MOZ_ALIGNED_DECL(uint8_t elem, 16);
};

template<typename T>
struct MOZ_INHERIT_TYPE_ANNOTATIONS_FROM_TEMPLATE_ARGS AlignedStorage2
{
  union U
  {
    char mBytes[sizeof(T)];
    uint64_t mDummy;
  } u;

  const T* addr() const { return reinterpret_cast<const T*>(u.mBytes); }
  T* addr() { return static_cast<T*>(static_cast<void*>(u.mBytes)); }

  AlignedStorage2() = default;

  // AlignedStorage2 is non-copyable: the default copy constructor violates
  // strict aliasing rules, per bug 1269319.
  AlignedStorage2(const AlignedStorage2&) = delete;
  void operator=(const AlignedStorage2&) = delete;
};

} /* namespace mozilla */

#endif /* mozilla_Alignment_h */