Перенос класса css в контент хэштега (#) & amp; При (@) содержании [закрыто]

Это перевернутый ответ. Вместо того, чтобы встраивать «эти объекты нужно синхронизировать» в качестве базы этого типа, вместо этого вставляйте под любым типом.

Вы имеете дело с синхронизированным объектом по-разному. Одна из серьезных проблем - вы должны беспокоиться о взаимоблокировках (блокировка нескольких объектов). Это также никогда не должно быть вашей «стандартной версией объекта»: синхронизированные объекты предназначены для объектов, которые будут в конфликте, и ваша цель должна заключаться в том, чтобы свести к минимуму конфликт между потоками, а не подметать его под ковер.

Но синхронизация объектов по-прежнему полезна. Вместо наследования от синхронизатора мы можем написать класс, который обертывает произвольный тип при синхронизации. Пользователи должны перейти через несколько обручей, чтобы выполнять операции над объектом теперь, когда они синхронизированы, но они не ограничены каким-то ограниченным набором операций с ограниченным ручным управлением для объекта. Они могут составлять несколько операций над объектом в один или работать с несколькими объектами.

Вот синхронизированная обертка вокруг произвольного типа T:

template
struct synchronized {
  template
  auto read(F&& f) const&->std::result_of_t {
    return access(std::forward(f), *this);
  }
  template
  auto read(F&& f) &&->std::result_of_t {
    return access(std::forward(f), std::move(*this));
  }
  template
  auto write(F&& f)->std::result_of_t {
    return access(std::forward(f), *this);
  }
  // uses `const` ness of Syncs to determine access:
  template
  friend auto access( F&& f, Syncs&&... syncs )->
  std::result_of_t< F(decltype(std::forward(syncs).t)...) >
  {
    return access2( std::index_sequence_for{}, std::forward(f), std::forward(syncs)... );
  };
  synchronized(synchronized const& o):t(o.read([](T const&o){return o;})){}
  synchronized(synchronized && o):t(std::move(o).read([](T&&o){return std::move(o);})){}  
  // special member functions:
  synchronized( T & o ):t(o) {}
  synchronized( T const& o ):t(o) {}
  synchronized( T && o ):t(std::move(o)) {}
  synchronized( T const&& o ):t(std::move(o)) {}
  synchronized& operator=(T const& o) {
    write([&](T& t){
      t=o;
    });
    return *this;
  }
  synchronized& operator=(T && o) {
    write([&](T& t){
      t=std::move(o);
    });
    return *this;
  }
private:
  template
  static auto smart_lock(S const& s) {
    return std::shared_lock< std::shared_timed_mutex >(s.m, X{});
  }
  template
  static auto smart_lock(S& s) {
    return std::unique_lock< std::shared_timed_mutex >(s.m, X{});
  }
  template
  static void lock(L& lockable) {
      lockable.lock();
  }
  template
  static void lock(Ls&... lockable) {
      std::lock( lockable... );
  }
  template
  friend auto access2( std::index_sequence, F&&f, Syncs&&...syncs)->
  std::result_of_t< F(decltype(std::forward(syncs).t)...) >
  {
    auto locks = std::make_tuple( smart_lock(syncs)... );
    lock( std::get(locks)... );
    return std::forward(f)(std::forward(syncs).t ...);
  }

  mutable std::shared_timed_mutex m;
  T t;
};
template
synchronized< T > sync( T&& t ) {
  return {std::forward(t)};
}

C ++ 14 и C ++ 1z.

это предполагает, что операции const являются безопасными с несколькими считывателями (что предполагает контейнер std).

Использовать внешний вид например:

synchronized x = 7;
x.read([&](auto&& v){
  std::cout << v << '\n';
});

для int с синхронизированным доступом.

Я бы посоветовал не иметь synchronized(synchronized const&). Это редко бывает необходимо.

Если вам нужно synchronized(synchronized const&), у меня возникнет соблазн заменить T t; на std::aligned_storage, разрешить конструкцию ручного размещения и ручное уничтожение. Это позволяет правильное управление жизненным циклом.

Если это не удалось, мы могли бы скопировать источник T, а затем прочитать из него:

synchronized(synchronized const& o):
  t(o.read(
    [](T const&o){return o;})
  )
{}
synchronized(synchronized && o):
  t(std::move(o).read(
    [](T&&o){return std::move(o);})
  )
{}

для назначения:

synchronized& operator=(synchronized const& o) {
  access([](T& lhs, T const& rhs){
    lhs = rhs;
  }, *this, o);
  return *this;
}
synchronized& operator=(synchronized && o) {
  access([](T& lhs, T&& rhs){
    lhs = std::move(rhs);
  }, *this, std::move(o));
  return *this;
}
friend void swap(synchronized& lhs, synchronized& rhs) {
  access([](T& lhs, T& rhs){
    using std::swap;
    swap(lhs, rhs);
  }, *this, o);
}

размещение и выровненные версии хранилищ немного беспорядочны. В большинстве случаев доступ к t будет заменен на функцию-член T&t() и T const&t()const, за исключением конструкции, где вам придется перепрыгивать через некоторые обручи.

Сделав synchronized вместо обертки части класса, все, что мы должны убедиться, состоит в том, что класс внутренне уважает const как многократный читатель и записывает его однопоточным способом.

В редких случаях нам нужно синхронизированный экземпляр, мы прыгаем через обручи, как показано выше.

Извините за любые опечатки в приведенном выше. Вероятно, есть некоторые.

. Преимущество вышеизложенного заключается в том, что n-арные произвольные операции над объектами synchronized (одного и того же типа) работают вместе, без необходимости жестко кодировать их перед началом работы. Добавить в объявление друга и n-ary synchronized объекты нескольких типов могут работать вместе. Мне может потребоваться переместить access из встроенного друга, чтобы иметь дело с перегрузками в этом случае.

live example

-3
задан blackcityhenry 16 January 2019 в 08:51
поделиться

2 ответа

Вы можете легко использовать метод Javascript .Split(), чтобы разделить строки на слова, а затем найти первый символ. Например:

$('li').each(function(e) {
  //Get full string as words
  var words = $(this).text().split(" ");
  for (var i = 0; i < words.length; i++) {
    if (words[i].charAt(0) == "#") {
      words[i] = "<span class=hashtag >" + words[i] + "</span>";
    }

    if (words[i].charAt(0) == "@") {
      words[i] = "<span class=at >" + words[i] + "</span>";
    }
  }

  $(this).html(words.join(" "));

});
.at {
  color: red;
}

.hashtag {
  color: blue
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li>I am a #hashtag</li>
<li>Hey @Bill, what's your #dog called?</li>
<li>Try to only process #letters, #numbers, and not #punctuation.</li>

Примечание: я сделал это, используя простой метод. Вам нужно будет обработать слова, чтобы обнаружить, что они являются буквами / цифрами и не содержат других символов.

0
ответ дан Dean Meehan 16 January 2019 в 08:51
поделиться

Вы также можете использовать match() для поиска ваших at и hash слов.

let myhtml = $('ul').html();
const mytypes = myhtml.match(/(@|#)+[^\s<\.]+/g);

const myReplace = (mytype) => {
  const isat = mytype.includes('@');
  const replacestring = `<span class="${isat ? 'at' : 'hash'}">${mytype}</span>`;
  myhtml = myhtml.replace(mytype, replacestring);
};

mytypes.forEach(el => myReplace(el));
$('ul').html(myhtml);
.at {
  color: red;
}

.hash {
  color: blue;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul>
<li>Phone call @Mary #group-project</li>
<li>Buy food and drinks #BBQ.</li>
<li>Discard old computer #home #computer</li>
</ul>

0
ответ дан d-h-e 16 January 2019 в 08:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: