text:
package com.hearthsim.test;

import com.hearthsim.card.minion.Minion;
import com.hearthsim.card.minion.MinionMock;
import org.junit.Test;

import static org.junit.Assert.*;

public class TestMinion {
    private static final int nT = 100;

    @Test
    public void testAttackDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setAttack((byte)10);
        assertEquals(10, copy.getAttack());
        assertEquals(3, minion0.getAttack());
    }

    @Test
    public void testAttackNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = new MinionMock("" + 0, (byte)2, (byte)30, (byte)4, (byte)3, (byte)4, (byte)4);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testAuraAttackDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setAuraAttack((byte)3);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setAuraAttack((byte)10);
        assertEquals(10, copy.getAuraAttack());
        assertEquals(3, minion0.getAuraAttack());
    }

    @Test
    public void testAuraAttackNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setAuraAttack((byte)3);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testAuraHealthDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setAuraHealth((byte)3);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setAuraHealth((byte)10);
        assertEquals(10, copy.getAuraHealth());
        assertEquals(3, minion0.getAuraHealth());
    }

    @Test
    public void testAuraHealthNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setAuraHealth((byte)3);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testChargeDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setCharge(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setCharge(false);
        assertFalse(copy.getCharge());
        assertTrue(minion0.getCharge());
    }

    @Test
    public void testChargeNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setCharge(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testDestroyOnTurnEndNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = (Minion)minion0.deepCopy();
        minion1.setDestroyOnTurnEnd(true);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testDestroyOnTurnStartNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = (Minion)minion0.deepCopy();
        minion1.setDestroyOnTurnStart(true);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testDivineShieldDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setDivineShield(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setDivineShield(false);
        assertFalse(copy.getDivineShield());
        assertTrue(minion0.getDivineShield());
    }

    @Test
    public void testDivineShieldNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setDivineShield(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        assertEquals(minion0, minion1);
        assertEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testEqualsRandom() {

        for (int iter = 0; iter < nT; ++iter) {
            byte mana = (byte)(Math.random() * 10);
            byte attack = (byte)(Math.random() * 10);
            byte health = (byte)(Math.random() * 10);
            Minion minion1 = new MinionMock("minion1", mana, attack, health, attack, health, health);
            Minion minion2 = new MinionMock("minion1", mana, attack, health, attack, health, health);
            assertEquals(minion1, minion2);
            assertEquals(minion2, minion1);
            assertEquals(minion1.hashCode(), minion2.hashCode());
        }
    }

    @Test
    public void testEqualsSelf() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        assertEquals(minion0, minion0);
    }

    @Test
    public void testFrozenDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setFrozen(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setFrozen(false);
        assertFalse(copy.getFrozen());
        assertTrue(minion0.getFrozen());
    }

    @Test
    public void testFrozenNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setFrozen(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testHasWindfuryAttackedDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.hasWindFuryAttacked(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.hasWindFuryAttacked(false);
        assertFalse(copy.hasWindFuryAttacked());
        assertTrue(minion0.hasWindFuryAttacked());
    }

    @Test
    public void testHasWindfuryAttackedNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.hasWindFuryAttacked(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testHealthNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)40, (byte)3, (byte)4, (byte)4);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testHeroTargetableDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setHeroTargetable(false);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setHeroTargetable(true);
        assertTrue(copy.isHeroTargetable());
        assertFalse(minion0.isHeroTargetable());
    }

    @Test
    public void testHeroTargetableNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setHeroTargetable(false);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testManaNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = new MinionMock("" + 0, (byte)20, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testMaxHealthNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)40);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testNameNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion minion1 = new MinionMock("" + 1, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        assertNotEquals(minion0, minion1);
        assertNotEquals(minion0.hashCode(), minion1.hashCode());
    }

    @Test
    public void testSpellDamageDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setSpellDamage((byte)3);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setSpellDamage((byte)10);
        assertEquals(10, copy.getSpellDamage());
        assertEquals(3, minion0.getSpellDamage());
    }

    @Test
    public void testSpellDamageNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setSpellDamage((byte)3);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testStealthedDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setStealthed(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setStealthed(false);
        assertFalse(copy.getStealthed());
        assertTrue(minion0.getStealthed());
    }

    @Test
    public void testStealthedNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setStealthed(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testTauntDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setTaunt(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setTaunt(false);
        assertFalse(copy.getTaunt());
        assertTrue(minion0.getTaunt());
    }

    @Test
    public void testTauntNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setTaunt(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }

    @Test
    public void testWindfuryDeepCopy() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        minion0.setWindfury(true);

        Minion copy = (Minion)minion0.deepCopy();
        assertEquals(minion0, copy);
        assertEquals(copy, minion0);
        assertEquals(minion0.hashCode(), copy.hashCode());

        // Verify the copy is a different object
        copy.setWindfury(false);
        assertFalse(copy.getWindfury());
        assertTrue(minion0.getWindfury());
    }

    @Test
    public void testWindfuryNotEquals() {
        Minion minion0 = new MinionMock("" + 0, (byte)2, (byte)3, (byte)4, (byte)3, (byte)4, (byte)4);
        Minion copy = (Minion)minion0.deepCopy();
        copy.setWindfury(true);
        assertNotEquals(minion0, copy);
        assertNotEquals(minion0.hashCode(), copy.hashCode());
    }
}


text:
using System;
using System.Threading;
using UnityEngine;
using ThreadPriority = System.Threading.ThreadPriority;

namespace Thinksquirrel.Fluvio.Internal.Threading
{
    class FluvioThreadPool : IThreadPool
    {
        readonly LockFreeQueue m_ActionQueue = new LockFreeQueue();
        readonly ManualResetEvent m_QueueIsNotEmptyEvent = new ManualResetEvent(false);
        [ThreadStatic] static int s_ThreadWaitTime;
        Thread[] m_WorkerThreads;
        bool m_ShouldStopThreads;
        int m_ThreadCount;
        bool m_Initialized;
        Task m_TaskObject = new Task();

        class Task
        {
            readonly ManualResetEvent m_IsFinished = new ManualResetEvent(true);
            volatile int m_TasksCompleted;
            int m_TaskCount;
            ParallelAction m_Action;

            internal int IncrementTask()
            {
                #pragma warning disable 420
                return Interlocked.Increment(ref m_TasksCompleted);
                #pragma warning restore 420
            }
            internal void ResetTask(int iterations, int chunkSize, ParallelAction action)
            {
                Wait();
                m_TasksCompleted = 0;
                m_Action = action;
                var taskCount = 0;
                for (var i = 0; i < iterations; i += chunkSize)
                {
                    taskCount++;
                }
                m_TaskCount = taskCount;
                m_IsFinished.Reset();
            }
            internal void SetFinished()
            {
                m_IsFinished.Set();
            }
            internal int GetTaskCount()
            {
                return m_TaskCount;
            }
            internal void Invoke(int index)
            {
                m_Action(index);
            }
            internal bool Wait()
            {
                return m_IsFinished.WaitOne();
            }
        }

        public FluvioThreadPool()
        {
            Initialize();
        }

        void Initialize()
        {
            m_ThreadCount = Mathf.Clamp(FluvioSettings.desiredThreads, 1, SystemInfo.processorCount - 1);

            m_ShouldStopThreads = false;
            m_WorkerThreads = new Thread[m_ThreadCount];

            var priority = (ThreadPriority)(int)FluvioSettings.threadPriority;

            for (var i = 0; i < m_ThreadCount; ++i)
            {
                var thread = new Thread(ExecuteThread) {Priority = priority, IsBackground = true};
                m_WorkerThreads[i] = thread;
                thread.Start();
            }
            m_Initialized = true;
        }
        public void SetPriority()
        {
            var priority = (ThreadPriority) (int) FluvioSettings.threadPriority;

            for (var i = 0; i < m_ThreadCount; ++i)
            {
                var thread = m_WorkerThreads[i];
                if (thread != null && (thread.IsAlive || thread.ThreadState == ThreadState.Unstarted))
                    thread.Priority = priority;
            }
        }

        public int GetThreadCount()
        {
            return m_ThreadCount;
        }

        public void Dispose()
        {
            if (!m_Initialized)
                return;

            m_ShouldStopThreads = true;

            for (var i = 0; i < m_ThreadCount; ++i)
            {
                var thread = m_WorkerThreads[i];

                if (thread.ThreadState == ThreadState.Unstarted) continue;

                thread.Join();
            }

            m_WorkerThreads = null;
            m_ShouldStopThreads = false;
            m_Initialized = false;
        }

        ~FluvioThreadPool()
        {
            Dispose();
        }

        public void For(int iterations, ParallelAction action)
        {
            DoFor(iterations, action, m_TaskObject);
        }
        public void RunInBackground(Action action)
        {
            if (!m_Initialized)
                Initialize();

            m_ActionQueue.Enqueue(action);
            m_QueueIsNotEmptyEvent.Set();
        }
        public int CompareExchange(ref int location1, int value, int comparand)
        {
            return Interlocked.CompareExchange(ref location1, value, comparand);
        }
        void DoFor(int iterations, ParallelAction action, Task task)
        {
            if (!m_Initialized)
                Initialize();

            // No multithreaded support
            if (!m_Initialized)
            {
                for (var i = 0; i < iterations; ++i)
                    action(i);

                return;
            }

            if (iterations == 0)
                return;

            var chunkSize = Mathf.Clamp(iterations/m_ThreadCount, 1, iterations);
            task.ResetTask(iterations, chunkSize, action);

            var id = 0;

            for (var i = 0; i < iterations; i += chunkSize)
            {
                var startIndex = id*chunkSize;
                var endIndex = Math.Min(startIndex + chunkSize, iterations);

                m_ActionQueue.Enqueue(() => DoTaskAction(task, startIndex, endIndex));
                m_QueueIsNotEmptyEvent.Set();

                ++id;
            }

            task.Wait();
        }

        void DoTaskAction(Task task, int startIndex, int endIndex)
        {
            for (var index = startIndex; index < endIndex; ++index)
                task.Invoke(index);

            if (task.IncrementTask() >= task.GetTaskCount())
                task.SetFinished();
        }
        void ExecuteThread()
        {
            s_ThreadWaitTime = 1;
            while (!m_ShouldStopThreads && m_ActionQueue != null)
            {
                // Wait
                if (!m_QueueIsNotEmptyEvent.WaitOne(s_ThreadWaitTime) && m_ActionQueue.isEmpty)
                {
                    if (s_ThreadWaitTime < 8)
                        s_ThreadWaitTime *= 2;
                    continue;
                }

                // Try to dequeue
                var action = m_ActionQueue.Dequeue();

                // We missed, queue is empty
                if (action == null)
                {
                    m_QueueIsNotEmptyEvent.Reset();
                    continue;
                }

                s_ThreadWaitTime = 1;

                try
                {
                    action();
                }
                catch (Exception e)
                {
                    if (!(e is ThreadAbortException))
                    {
                        FluvioDebug.LogError(string.Format("Unhandled {0} caught on background thread ({1}) - task aborted.\n{2}", e.GetType().Name, e.Message, e.StackTrace), this);
                    }
                }
            }
        }
    }
}

#endif

redpajama_set_name: RedPajamaGithub


text:
require 'spec_helper'

describe SynchronizationOauth do

  before(:all) do
    @user = create_user(:quota_in_bytes => 500.megabytes, :table_quota => 500)
    @user.reload
  end

  after(:all) do
    bypass_named_maps
    @user.destroy
  end

  after(:each) do
    # @user.synchronization_oauths.map &:destroy
    @user.reload
  end

  # Skipped because this is being substituted by Connections
  before { pending }

  context '#creation_updating' do
    it 'Tests basic creation operations' do
      service_name = 'testtest'
      token_value = 'qv2345q235erfaweerfdsdfsds'
      token_value_2 = 'aaaaaaaaaaaaaaaaaaaaaaaa'

      SynchronizationOauth.all.size.should eq 0

      oauth_entry = SynchronizationOauth.create(
          user_id: @user.id,
          service: service_name,
          token: token_value
      ).reload

      oauth_entry.nil?.should eq false
      oauth_entry.user_id.should eq @user.id
      oauth_entry.service.should eq service_name
      oauth_entry.token.should eq token_value

      SynchronizationOauth.all.size.should eq 1

      entry_second_handle = SynchronizationOauth.where(user_id: @user.id, service: service_name).first
      entry_second_handle.nil?.should eq false
      entry_second_handle.user_id.should eq @user.id
      entry_second_handle.service.should eq service_name
      entry_second_handle.token.should eq token_value

      entry_second_handle.should eq oauth_entry

      oauth_entry.token = token_value_2
      oauth_entry.save.reload
      oauth_entry.token.should eq token_value_2

      expect {
        oauth_entry.service = 'another_service_name'
        oauth_entry.save
      }.to raise_exception Sequel::ValidationFailed
      oauth_entry.service = service_name

      expect {
        oauth_entry.user_id = Carto::UUIDHelper.random_uuid
        oauth_entry.save
      }.to raise_exception Sequel::ValidationFailed

      expect {
        SynchronizationOauth.create(
            user_id: @user.id,
            service: service_name,
            token: Carto::UUIDHelper.random_uuid
        )
      }.to raise_exception Sequel::ValidationFailed

      expect {
        SynchronizationOauth.create(
          user_id: @user_id,
          service: service_name,
          token: nil
        )
      }.to raise_exception Sequel::ValidationFailed

      expect {
        SynchronizationOauth.create(
          user_id: @user_id,
          service: service_name,
          token: ''
        )
      }.to raise_exception Sequel::ValidationFailed
    end
  end

  context '#deletion' do
    it 'tests deletion of items' do
      another_uuid = Carto::UUIDHelper.random_uuid
      service_name = 'testtest'
      service_name_2 = '123456'
      token_value = 'qv2345q235erfaweerfdsdfsds'
      token_value_2 = 'aaaaaaaaaaaaaaaaaaaaaaaa'

      SynchronizationOauth.create(
          user_id: @user.id,
          service: service_name,
          token: token_value
      )
      SynchronizationOauth.create(
          user_id: @user.id,
          service: service_name_2,
          token: token_value_2
      )
      SynchronizationOauth.create(
          user_id: another_uuid,
          service: service_name_2,
          token: token_value_2
      )

      @user.synchronization_oauths.size.should eq 2

      oauth = SynchronizationOauth.where(user_id: @user.id, service: service_name).first
      oauth.destroy
      @user.reload
      @user.synchronization_oauths.size.should eq 1

      oauth = SynchronizationOauth.where(user_id: @user.id, service: service_name_2).first
      oauth.destroy
      @user.reload
      @user.synchronization_oauths.size.should eq 0
    end
  end

  context '#user_oauths' do
    it 'tests the one to many association of user and sync oauths' do
      service_name = 'testtest'
      token_value = 'qv2345q235erfaweerfdsdfsds'

      @user.synchronization_oauths.size.should eq 0

      SynchronizationOauth.create(
          user_id: @user.id,
          service: service_name,
          token: token_value
      )
      @user.reload
      @user.synchronization_oauths.size.should eq 1

      retrieved_entry = @user.synchronization_oauths.first
      @user.synchronization_oauths.first.should eq retrieved_entry

      @user.synchronization_oauths.first.destroy
      @user.reload
      @user.synchronization_oauths.size.should eq 0

      @user.add_synchronization_oauth(service: service_name, token: token_value)
      @user.synchronization_oauths.size.should eq 1

      expect {
        @user.add_synchronization_oauth(service: service_name, token: token_value)
      }.to raise_exception Sequel::ValidationFailed

    end
  end

end


text:
'use strict'

var GITHUB_TOKEN;
var GITHUB_QUERY;

var FORM_SELECTOR          = 'div.sidebar-assignee';
var ASSIGN_BUTTON_SELECTOR = FORM_SELECTOR + ' button.discussion-sidebar-toggle';
var USER_SELECTOR          = 'div [role="menuitem"]';

chrome.storage.sync.get(null, function (storage) {
  GITHUB_TOKEN = storage.githubAccessToken;
  GITHUB_QUERY = storage.githubQuery;
});

$(document).on('click', ASSIGN_BUTTON_SELECTOR, function() {
  if (GITHUB_TOKEN && GITHUB_QUERY) {

    var userElements = $(FORM_SELECTOR).find($(USER_SELECTOR));

    userElements.each(function () {
      addLoadingIcon(this);
    })
    .promise()
    .done(function () {
      $.get('https://api.github.com/search/issues?access_token=' + GITHUB_TOKEN + '&q=' + GITHUB_QUERY).done(function(data) {
        var stats = countAsignees(data.items);

        userElements.each(function() {
          addUserDetails(this, stats);
        });
      });
    });
  }
});

function countAsignees (issues) {
  return issues.reduce(function (stats, issue) {
    if (issue.assignee) {
      if (!stats[issue.assignee.id]) {
        stats[issue.assignee.id] = 0;
      }

      stats[issue.assignee.id] += 1;
    }

    return stats;
  }, {});
}

function addLoadingIcon (element) {
  $(element).find($('span.description')).html(
    $('<div>').css('background', 'url(' + chrome.extension.getURL('./img/loading.svg') + ') center').css('display', 'inline-block').css('width', '14px').css('height', '14px')
  );
}

function addUserDetails (element, stats) {
  var el = $(element);
  var userId = el.find('input').val();

  el.data('pr_count', stats[userId] || 0);
  el.click(handlePRToggle);
  el.on('updatePRCount', function () { el.find($('span.description')).html(' - ' + el.data('pr_count')); });
  el.trigger('updatePRCount');
}

function handlePRToggle () {
  var el = $(this);
  el.data('pr_count', el.data('pr_count') + (!el.hasClass('selected') ? 1 : -1));
  el.trigger('updatePRCount');
}


text:
DEFINE_string(scratch_dirs, "/tmp", "Writable scratch directories");

#include "common/names.h"

using boost::algorithm::is_any_of;
using boost::algorithm::join;
using boost::algorithm::split;
using boost::algorithm::token_compress_on;
using boost::filesystem::absolute;
using boost::filesystem::path;
using boost::uuids::random_generator;
using namespace strings;

namespace impala {

const string TMP_SUB_DIR_NAME = "impala-scratch";
const uint64_t AVAILABLE_SPACE_THRESHOLD_MB = 1024;

// Metric keys
const string TMP_FILE_MGR_ACTIVE_SCRATCH_DIRS = "tmp-file-mgr.active-scratch-dirs";
const string TMP_FILE_MGR_ACTIVE_SCRATCH_DIRS_LIST =
    "tmp-file-mgr.active-scratch-dirs.list";

TmpFileMgr::TmpFileMgr() : initialized_(false), dir_status_lock_(), tmp_dirs_(),
  num_active_scratch_dirs_metric_(NULL), active_scratch_dirs_metric_(NULL) {}

Status TmpFileMgr::Init(MetricGroup* metrics) {
  string tmp_dirs_spec = FLAGS_scratch_dirs;
  vector<string> all_tmp_dirs;
  // Empty string should be interpreted as no scratch
  if (!tmp_dirs_spec.empty()) {
    split(all_tmp_dirs, tmp_dirs_spec, is_any_of(","), token_compress_on);
  }
  return InitCustom(all_tmp_dirs, true, metrics);
}

Status TmpFileMgr::InitCustom(const vector<string>& tmp_dirs, bool one_dir_per_device,
      MetricGroup* metrics) {
  DCHECK(!initialized_);
  if (tmp_dirs.empty()) {
    LOG(WARNING) << "Running without spill to disk: no scratch directories provided.";
  }

  vector<bool> is_tmp_dir_on_disk(DiskInfo::num_disks(), false);
  // For each tmp directory, find the disk it is on,
  // so additional tmp directories on the same disk can be skipped.
  for (int i = 0; i < tmp_dirs.size(); ++i) {
    path tmp_path(trim_right_copy_if(tmp_dirs[i], is_any_of("/")));
    tmp_path = absolute(tmp_path);
    path scratch_subdir_path(tmp_path / TMP_SUB_DIR_NAME);
    // tmp_path must be a writable directory.
    Status status = FileSystemUtil::VerifyIsDirectory(tmp_path.string());
    if (!status.ok()) {
      LOG(WARNING) << "Cannot use directory " << tmp_path.string() << " for scratch: "
                   << status.msg().msg();
      continue;
    }
    // Find the disk id of tmp_path. Add the scratch directory if there isn't another
    // directory on the same disk (or if we don't know which disk it is on).
    int disk_id = DiskInfo::disk_id(tmp_path.c_str());
    if (!one_dir_per_device || disk_id < 0 || !is_tmp_dir_on_disk[disk_id]) {
      uint64_t available_space;
      RETURN_IF_ERROR(FileSystemUtil::GetSpaceAvailable(tmp_path.string(),
          &available_space));
      if (available_space < AVAILABLE_SPACE_THRESHOLD_MB * 1024 * 1024) {
        LOG(WARNING) << "Filesystem containing scratch directory " << tmp_path
                     << " has less than " << AVAILABLE_SPACE_THRESHOLD_MB
                     << "MB available.";
      }
      // Create the directory, destroying if already present. If this succeeds, we will
      // have an empty writable scratch directory.
      status = FileSystemUtil::CreateDirectory(scratch_subdir_path.string());
      if (status.ok()) {
        if (disk_id >= 0) is_tmp_dir_on_disk[disk_id] = true;
        LOG(INFO) << "Using scratch directory " << scratch_subdir_path.string() << " on disk "
                  << disk_id;
        tmp_dirs_.push_back(Dir(scratch_subdir_path.string(), false));
      } else {
        LOG(WARNING) << "Could not remove and recreate directory "
                     << scratch_subdir_path.string() << ": cannot use it for scratch. "
                     << "Error was: " << status.msg().msg();
      }
    }
  }

  DCHECK(metrics != NULL);
  num_active_scratch_dirs_metric_ =
      metrics->AddGauge(TMP_FILE_MGR_ACTIVE_SCRATCH_DIRS, 0L);
  active_scratch_dirs_metric_ = SetMetric<string>::CreateAndRegister(metrics,
      TMP_FILE_MGR_ACTIVE_SCRATCH_DIRS_LIST, set<string>());
  num_active_scratch_dirs_metric_->set_value(tmp_dirs_.size());
  for (int i = 0; i < tmp_dirs_.size(); ++i) {
    active_scratch_dirs_metric_->Add(tmp_dirs_[i].path());
  }

  initialized_ = true;

  if (tmp_dirs_.empty() && !tmp_dirs.empty()) {
    LOG(ERROR) << "Running without spill to disk: could not use any scratch "
               << "directories in list: " << join(tmp_dirs, ",")
               << ". See previous warnings for information on causes.";
  }
  return Status::OK();
}

Status TmpFileMgr::GetFile(const DeviceId& device_id, const TUniqueId& query_id,
    File** new_file) {
  DCHECK(initialized_);
  DCHECK_GE(device_id, 0);
  DCHECK_LT(device_id, tmp_dirs_.size());
  if (IsBlacklisted(device_id)) {
    return Status(TErrorCode::TMP_DEVICE_BLACKLISTED, tmp_dirs_[device_id].path());
  }

  // Generate the full file path.
  string unique_name = lexical_cast<string>(random_generator()());
  stringstream file_name;
  file_name << PrintId(query_id) << "_" << unique_name;
  path new_file_path(tmp_dirs_[device_id].path());
  new_file_path /= file_name.str();

  *new_file = new File(this, device_id, new_file_path.string());
  return Status::OK();
}

string TmpFileMgr::GetTmpDirPath(DeviceId device_id) const {
  DCHECK(initialized_);
  DCHECK_GE(device_id, 0);
  DCHECK_LT(device_id, tmp_dirs_.size());
  return tmp_dirs_[device_id].path();
}

void TmpFileMgr::BlacklistDevice(DeviceId device_id) {
  DCHECK(initialized_);
  DCHECK(device_id >= 0 && device_id < tmp_dirs_.size());
  bool added;
  {
    lock_guard<SpinLock> l(dir_status_lock_);
    added = tmp_dirs_[device_id].blacklist();
  }
  if (added) {
    num_active_scratch_dirs_metric_->Increment(-1);
    active_scratch_dirs_metric_->Remove(tmp_dirs_[device_id].path());
  }
}

bool TmpFileMgr::IsBlacklisted(DeviceId device_id) {
  DCHECK(initialized_);
  DCHECK(device_id >= 0 && device_id < tmp_dirs_.size());
  lock_guard<SpinLock> l(dir_status_lock_);
  return tmp_dirs_[device_id].is_blacklisted();
}

int TmpFileMgr::num_active_tmp_devices() {
  DCHECK(initialized_);
  lock_guard<SpinLock> l(dir_status_lock_);
  int num_active = 0;
  for (int device_id = 0; device_id < tmp_dirs_.size(); ++device_id) {
    if (!tmp_dirs_[device_id].is_blacklisted()) ++num_active;
  }
  return num_active;
}

vector<TmpFileMgr::DeviceId> TmpFileMgr::active_tmp_devices() {
  vector<TmpFileMgr::DeviceId> devices;
  // Allocate vector before we grab lock
  devices.reserve(tmp_dirs_.size());
  {
    lock_guard<SpinLock> l(dir_status_lock_);
    for (DeviceId device_id = 0; device_id < tmp_dirs_.size(); ++device_id) {
      if (!tmp_dirs_[device_id].is_blacklisted()) {
        devices.push_back(device_id);
      }
    }
  }
  return devices;
}

TmpFileMgr::File::File(TmpFileMgr* mgr, DeviceId device_id, const string& path)
  : mgr_(mgr),
    path_(path),
    device_id_(device_id),
    current_size_(0),
    blacklisted_(false) {
}

Status TmpFileMgr::File::AllocateSpace(int64_t write_size, int64_t* offset) {
  DCHECK_GT(write_size, 0);
  Status status;
  if (mgr_->IsBlacklisted(device_id_)) {
    blacklisted_ = true;
    return Status(TErrorCode::TMP_FILE_BLACKLISTED, path_);
  }
  if (current_size_ == 0) {
    // First call to AllocateSpace. Create the file.
    status = FileSystemUtil::CreateFile(path_);
    if (!status.ok()) {
      ReportIOError(status.msg());
      return status;
    }
    disk_id_ = DiskInfo::disk_id(path_.c_str());
  }
  int64_t new_size = current_size_ + write_size;
  status = FileSystemUtil::ResizeFile(path_, new_size);
  if (!status.ok()) {
    ReportIOError(status.msg());
    return status;
  }
  *offset = current_size_;
  current_size_ = new_size;
  return Status::OK();
}

void TmpFileMgr::File::ReportIOError(const ErrorMsg& msg) {
  LOG(ERROR) << "Error for temporary file '" << path_ << "': " << msg.msg();
  // IMPALA-2305: avoid blacklisting to prevent test failures.
  // blacklisted_ = true;
  // mgr_->BlacklistDevice(device_id_);
}

Status TmpFileMgr::File::Remove() {
  if (current_size_ > 0) FileSystemUtil::RemovePaths(vector<string>(1, path_));
  return Status::OK();
}

} //namespace impala


text:
/**
  ******************************************************************************
  * @brief   CAN functions of the firmware library.
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "gd32f10x_can.h"
#include "gd32f10x_rcc.h"

/** @addtogroup GD32F10x_Firmware
  * @{
  */

/** @defgroup CAN
  * @brief CAN driver modules
  * @{
  */

/** @defgroup CAN_Private_Defines
  * @{
  */

/* CAN Mailbox Transmit Request */
#define CAN_TMIR_TE                       ((uint32_t)0x00000001)

/* CAN Filter Master Register bits */
#define FMR_FINIT                         ((uint32_t)0x00000001)

/* Time out for IWS bit */
#define IWS_TIMEOUT                       ((uint32_t)0x0000FFFF)
/* Time out for SWS bit */
#define SWS_TIMEOUT                       ((uint32_t)0x0000FFFF)

/* CAN TMIR_StdId masks */
#define CAN_TMIR_StdId_Mask               ((uint32_t)0x000007FF)

/* CAN TMIR_ExtId masks */
#define CAN_TMIR_ExtId_Mask               ((uint32_t)0x1FFFFFFF)

/* CAN TMIR_ExtId masks */
#define CAN_FLAG_Mask                     ((uint32_t)0x000FFFFF)

/* Flags in TSTR register */
#define CAN_FLAGS_TSTR                    ((uint32_t)0x08000000)

/* Flags in RFR1 register */
#define CAN_FLAGS_RFR1                    ((uint32_t)0x04000000)

/* Flags in RFR0register */
#define CAN_FLAGS_RFR0                    ((uint32_t)0x02000000)

/* Flags in STR register */
#define CAN_FLAGS_STR                     ((uint32_t)0x01000000)

/* Flags in ER register */
#define CAN_FLAGS_ER                      ((uint32_t)0x00F00000)

/* Mailboxes definition */
#define CAN_TXMAILBOX_0                   ((uint8_t)0x00)
#define CAN_TXMAILBOX_1                   ((uint8_t)0x01)
#define CAN_TXMAILBOX_2                   ((uint8_t)0x02)

/* CAN Master Control Register bit */
#define MCR_DBF                           ((uint32_t)0x00010000)

#define CAN_MODE_MASK                     ((uint32_t)0x00000003)
/**
  * @}
  */

/** @defgroup CAN_Private_Functions
  * @{
  */

/**
  * @brief  Deinitialize the CAN peripheral registers.
  * @param  CANx: where x:[1,2] to select the CAN peripheral.
  * @retval None.
  */
void CAN_DeInit(CAN_TypeDef *CANx)
{
    if (CANx == CAN1) {
        /* Force CAN1 reset state */
        RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_CAN1, ENABLE);
        /* Release CAN1 from reset state */
        RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_CAN1, DISABLE);
    } else {
        /* Force CAN2 reset state */
        RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_CAN2, ENABLE);
        /* Release CAN2 from reset state */
        RCC_APB1PeriphReset_Enable(RCC_APB1PERIPH_CAN2, DISABLE);
    }
}

/**
  * @brief  Initialize the CAN peripheral according to the CAN_InitParaStruct.
  * @param  CANx:where x:[1,2]
  * @param  CAN_InitParaStruct: contain the configuration information for the CAN peripheral.
  * @retval It will be returned the status of CAN_INITSTATE_FAILED or CAN_INITSTATE_SUCCESS.
  */
uint8_t CAN_Init(CAN_TypeDef *CANx, CAN_InitPara *CAN_InitParaStruct)
{
    uint32_t wait_ack = 0x00000000;

    /* Out of sleep mode */
    CANx->CTLR &= (~(uint32_t)CAN_CTLR_SWM);

    /* Enable initial working */
    CANx->CTLR |= CAN_CTLR_IWM ;

    /* Wait the acknowledge */
    while (((CANx->STR & CAN_STR_IWS) != CAN_STR_IWS) && (wait_ack != IWS_TIMEOUT)) {
        wait_ack++;
    }

    /* Check whether initial working is success */
    if ((CANx->STR & CAN_STR_IWS) != CAN_STR_IWS) {
        return CAN_INITSTATE_FAILED;
    } else {
        /* Set the time triggered communication mode */
        if (CAN_InitParaStruct->CAN_TTC == ENABLE) {
            CANx->CTLR |= CAN_CTLR_TTC;
        } else {
            CANx->CTLR &= ~(uint32_t)CAN_CTLR_TTC;
        }

        /* Set the automatic bus-off management */
        if (CAN_InitParaStruct->CAN_ABOR == ENABLE) {
            CANx->CTLR |= CAN_CTLR_ABOR;
        } else {
            CANx->CTLR &= ~(uint32_t)CAN_CTLR_ABOR;
        }

        /* Set the automatic wake-up mode */
        if (CAN_InitParaStruct->CAN_AWK == ENABLE) {
            CANx->CTLR |= CAN_CTLR_AWK;
        } else {
            CANx->CTLR &= ~(uint32_t)CAN_CTLR_AWK;
        }

        /* Set the automatic retransmission mode */
        if (CAN_InitParaStruct->CAN_ARD == ENABLE) {
            CANx->CTLR |= CAN_CTLR_ARD;
        } else {
            CANx->CTLR &= ~(uint32_t)CAN_CTLR_ARD;
        }

        /* Set receive FIFO overwrite mode */
        if (CAN_InitParaStruct->CAN_RFOD == ENABLE) {
            CANx->CTLR |= CAN_CTLR_RFOD;
        } else {
            CANx->CTLR &= ~(uint32_t)CAN_CTLR_RFOD;
        }

        /* Set the Transmit FIFO order */
        if (CAN_InitParaStruct->CAN_TFO == ENABLE) {
            CANx->CTLR |= CAN_CTLR_TFO;
        } else {
            CANx->CTLR &= ~(uint32_t)CAN_CTLR_TFO;
        }

        /* Set the bit timing register */
        CANx->BTR = (uint32_t)((uint32_t)CAN_InitParaStruct->CAN_Mode << 30) | \
                    ((uint32_t)CAN_InitParaStruct->CAN_SJW << 24) | \
                    ((uint32_t)CAN_InitParaStruct->CAN_BS1 << 16) | \
                    ((uint32_t)CAN_InitParaStruct->CAN_BS2 << 20) | \
                    ((uint32_t)CAN_InitParaStruct->CAN_Prescaler - 1);

        /* leave initialisation */
        CANx->CTLR &= ~(uint32_t)CAN_CTLR_IWM;

        /* Wait the acknowledge */
        wait_ack = 0;

        while (((CANx->STR & CAN_STR_IWS) == CAN_STR_IWS) && (wait_ack != IWS_TIMEOUT)) {
            wait_ack++;
        }

        /* Check whether qiut initial working mode */
        if ((CANx->STR & CAN_STR_IWS) == CAN_STR_IWS) {
            return CAN_INITSTATE_FAILED;
        } else {
            return CAN_INITSTATE_SUCCESS;
        }
    }

}

/**
  * @brief  Initialize the CAN peripheral according to the CAN_FilterInitStruct.
  * @param  CAN_FilterInitParaStruct:contain the information for the CAN peripheral.
  * @retval None.
  */
void CAN_FilterInit(CAN_FilterInitPara *CAN_FilterInitParaStruct)
{
    uint32_t filter_number = 0;

    filter_number = ((uint32_t)1) << CAN_FilterInitParaStruct->CAN_FilterNumber;

    /* Set filter lock disable */
    CAN1->FCTLR |= CAN_FCTLR_FLD;

    /* Disable Filter */
    CAN1->FWR &= ~(uint32_t)filter_number;

    /* Filter Scale */
    if (CAN_FilterInitParaStruct->CAN_FilterScale == CAN_FILTERSCALE_16BIT) {
        /* Set the filter 16-bit scale*/
        CAN1->FSR &= ~(uint32_t)filter_number;

        /* First 16-bit list and First 16-bit mask */
        /* Or First 16-bit list and Second 16-bit list */
        CAN1->FilterRegister[CAN_FilterInitParaStruct->CAN_FilterNumber].FD0R =
            ((0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterMaskListLow) << 16) |
            (0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterListLow);

        /* Second 16-bit identifier and Second 16-bit mask */
        /* Or Third 16-bit identifier and Fourth 16-bit identifier */
        CAN1->FilterRegister[CAN_FilterInitParaStruct->CAN_FilterNumber].FD1R =
            ((0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterMaskListHigh) << 16) |
            (0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterListHigh);
    }

    if (CAN_FilterInitParaStruct->CAN_FilterScale == CAN_FILTERSCALE_32BIT) {
        /* 32-bit scale for the filter */
        CAN1->FSR |= filter_number;
        /* 32-bit identifier or First 32-bit identifier */
        CAN1->FilterRegister[CAN_FilterInitParaStruct->CAN_FilterNumber].FD0R =
            ((0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterListHigh) << 16) |
            (0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterListLow);
        /* 32-bit mask or Second 32-bit identifier */
        CAN1->FilterRegister[CAN_FilterInitParaStruct->CAN_FilterNumber].FD1R =
            ((0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterMaskListHigh) << 16) |
            (0x0000FFFF & (uint32_t)CAN_FilterInitParaStruct->CAN_FilterMaskListLow);
    }

    /* Filter Mode */
    if (CAN_FilterInitParaStruct->CAN_FilterMode == CAN_FILTERMODE_MASK) {
        /*Filter with Mask mode*/
        CAN1->FMR &= ~(uint32_t)filter_number;
    } else { /* CAN_FilterInitStruct->CAN_FilterMode == CAN_FILTERMODE_LIST */
        /*Filter with List mode*/
        CAN1->FMR |= (uint32_t)filter_number;
    }

    /* Filter associated with FIFO */
    if (CAN_FilterInitParaStruct->CAN_FilterFIFOAssociation == CAN_FILTER_FIFO0) {
        /* Filter associated with FIFO 0 */
        CAN1->FAFR &= ~(uint32_t)filter_number;
    }

    if (CAN_FilterInitParaStruct->CAN_FilterFIFOAssociation == CAN_FILTER_FIFO1) {
        /* Filter associated with FIFO 1 */
        CAN1->FAFR |= (uint32_t)filter_number;
    }

    /* Filter working */
    if (CAN_FilterInitParaStruct->CAN_FilterWork == ENABLE) {
        CAN1->FWR |= filter_number;
    }

    /* Exit the initialisation mode for the filter */
    CAN1->FCTLR &= ~CAN_FCTLR_FLD;
}

/**
  * @brief  Configure each CAN_InitParaStruct member with default value.
  * @param  CAN_InitParaStruct: pointer to a CAN_InitPara structure to initialize.
  * @retval None.
  */
void CAN_StructInit(CAN_InitPara *CAN_InitParaStruct)
{
    /* Set the time triggered communication mode */
    CAN_InitParaStruct->CAN_TTC = DISABLE;

    /* Set the automatic bus-off recovery */
    CAN_InitParaStruct->CAN_ABOR = DISABLE;

    /* Set the automatic wake up mode */
    CAN_InitParaStruct->CAN_AWK = DISABLE;

    /* Set the automatic retransmission disable */
    CAN_InitParaStruct->CAN_ARD = DISABLE;

    /* Set the receive FIFO overwrite mode */
    CAN_InitParaStruct->CAN_RFOD = DISABLE;

    /* Set the transmit FIFO order */
    CAN_InitParaStruct->CAN_TFO = DISABLE;

    /* Set the CAN_Mode member */
    CAN_InitParaStruct->CAN_Mode = CAN_MODE_NORMAL;

    /* Set the CAN_SJW member */
    CAN_InitParaStruct->CAN_SJW = CAN_SJW_1TQ;

    /* Set the CAN_BS1 member */
    CAN_InitParaStruct->CAN_BS1 = CAN_BS1_4TQ;

    /* Set the CAN_BS2 member */
    CAN_InitParaStruct->CAN_BS2 = CAN_BS2_3TQ;

    /* Set the CAN_Prescaler member */
    CAN_InitParaStruct->CAN_Prescaler = 1;
}

/**
  * @brief  Set header bank of CAN2 filter.
  * @param  CAN2_HeaderBankNumber: Select header bank of CAN2 filter.It can be 1 to 27.
  * @retval None.
  */
void CAN_HeaderBank(uint8_t CAN_HeaderBankNumber)
{
    /* Set filter lock disable */
    CAN1->FCTLR |= CAN_FCTLR_FLD;

    /* Select filter start number for slave CAN */
    CAN1->FCTLR &= (uint32_t)0xFFFFC0F1 ;
    CAN1->FCTLR |= (uint32_t)(CAN_HeaderBankNumber) << 8;

    /* Filter out the initialization mode */
    CAN1->FCTLR |= ~CAN_FCTLR_FLD;
}

/**
  * @brief  Enable or disable the Debug Freeze for CAN.
  * @param  CANx: where x :[1,2] for selecting the CAN peripheral.
  * @param  NewValue: new state of the CAN peripheral.
  *   This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void CAN_DebugFreeze(CAN_TypeDef *CANx, TypeState NewValue)
{
    if (NewValue != DISABLE) {
        CANx->CTLR |= CAN_CTLR_DFZ;
    } else {
        CANx->CTLR &= ~CAN_CTLR_DFZ;
    }
}

/**
  * @brief  Enable or disabe the CAN Time Triggered communication mode.
  * @param  CANx:where x :[1,2] for selecting the CAN peripheral.
  * @param  NewValue : Mode new state , This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void CAN_TimeTrigComMode_Enable(CAN_TypeDef *CANx, TypeState NewValue)
{
    if (NewValue != DISABLE) {
        /* Enable the TTC mode */
        CANx->CTLR |= CAN_CTLR_TTC;

        /* Set TSEbits */
        CANx->TxMailBox[0].TMPR |= ((uint32_t)CAN_TMPR0_TSE);
        CANx->TxMailBox[1].TMPR |= ((uint32_t)CAN_TMPR1_TSE);
        CANx->TxMailBox[2].TMPR |= ((uint32_t)CAN_TMPR2_TSE);
    } else {
        /* Disable the TTC mode */
        CANx->CTLR &= (uint32_t)(~(uint32_t)CAN_CTLR_TTC);

        /* Reset TSE bits */
        CANx->TxMailBox[0].TMPR &= ((uint32_t)~CAN_TMPR0_TSE);
        CANx->TxMailBox[1].TMPR &= ((uint32_t)~CAN_TMPR1_TSE);
        CANx->TxMailBox[2].TMPR &= ((uint32_t)~CAN_TMPR2_TSE);
    }
}
/**
  * @brief  Initiate to transmit a message.
  * @param  CANx: where x:[1,2]to to select the CAN peripheral.
  * @param  TxMessage: contain CAN Id, CAN DLC and CAN data for the structure.
  * @retval The number of the mailbox that is used for transmission
  *         or CAN_TxState_NoMailBox if there is no empty mailbox.
  */
uint8_t CAN_Transmit(CAN_TypeDef *CANx, CanTxMessage *TxMessage)
{
    uint8_t transmit_mailbox_number = 0;

    /* Select one empty transmit mailbox */
    if ((CANx->TSTR & CAN_TSTR_TME0) == CAN_TSTR_TME0) {
        transmit_mailbox_number = 0;
    } else if ((CANx->TSTR & CAN_TSTR_TME1) == CAN_TSTR_TME1) {
        transmit_mailbox_number = 1;
    } else if ((CANx->TSTR & CAN_TSTR_TME2) == CAN_TSTR_TME2) {
        transmit_mailbox_number = 2;
    } else {
        transmit_mailbox_number = CAN_TXSTATE_NOMAILBOX;
    }

    if (transmit_mailbox_number != CAN_TXSTATE_NOMAILBOX) {
        /* Set up the Id */
        CANx->TxMailBox[transmit_mailbox_number].TMIR &= CAN_TMIR_TE;
        if (TxMessage->FF == CAN_FF_STANDARD) {
            CANx->TxMailBox[transmit_mailbox_number].TMIR |= ((TxMessage->StdId << 21) | \
                    TxMessage->FT);
        } else {
            CANx->TxMailBox[transmit_mailbox_number].TMIR |= ((TxMessage->ExtId << 3) | \
                    TxMessage->FF | \
                    TxMessage->FT);
        }

        /* Set up the DLC */
        TxMessage->DLC &= ((uint8_t)CAN_TMPR0_DLC);
        CANx->TxMailBox[transmit_mailbox_number].TMPR &= ((uint32_t)~CAN_TMPR0_DLC);
        CANx->TxMailBox[transmit_mailbox_number].TMPR |= TxMessage->DLC;

        /* Set up the data field */
        CANx->TxMailBox[transmit_mailbox_number].TMD0R = (((uint32_t)TxMessage->Data[3] << 24) |
                ((uint32_t)TxMessage->Data[2] << 16) |
                ((uint32_t)TxMessage->Data[1] << 8) |
                ((uint32_t)TxMessage->Data[0]));
        CANx->TxMailBox[transmit_mailbox_number].TMD1R = (((uint32_t)TxMessage->Data[7] << 24) |
                ((uint32_t)TxMessage->Data[6] << 16) |
                ((uint32_t)TxMessage->Data[5] << 8) |
                ((uint32_t)TxMessage->Data[4]));
        /* Request transmission */
        CANx->TxMailBox[transmit_mailbox_number].TMIR |= CAN_TMIR0_TE;
    }
    return transmit_mailbox_number;
}

/**
  * @brief  Check the state of message transmission.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  TransmitMailbox: the number of the used transmission mailbox.
  * @retval Return CAN_TXSTATE_OK or CAN_TXSTATE_FAILED.
  */
uint8_t CAN_TransmitState(CAN_TypeDef *CANx, uint8_t TransmitMailbox)
{
    uint32_t state = 0;

    switch (TransmitMailbox) {
    case (CAN_TXMAILBOX_0):
        state =   CANx->TSTR & (CAN_TSTR_MTF0 | CAN_TSTR_MTFNE0 | CAN_TSTR_TME0);
        break;
    case (CAN_TXMAILBOX_1):
        state =   CANx->TSTR & (CAN_TSTR_MTF1 | CAN_TSTR_MTFNE1 | CAN_TSTR_TME1);
        break;
    case (CAN_TXMAILBOX_2):
        state =   CANx->TSTR & (CAN_TSTR_MTF2 | CAN_TSTR_MTFNE2 | CAN_TSTR_TME2);
        break;
    default:
        state = CAN_TXSTATE_FAILED;
        break;
    }
    switch (state) {
    /* transmit pending  */
    case (0x0):
        state = CAN_TXSTATE_PENDING;
        break;
    /* transmit failed  */
    case (CAN_TSTR_MTF0 | CAN_TSTR_TME0):
        state = CAN_TXSTATE_FAILED;
        break;
    case (CAN_TSTR_MTF1 | CAN_TSTR_TME1):
        state = CAN_TXSTATE_FAILED;
        break;
    case (CAN_TSTR_MTF2 | CAN_TSTR_TME2):
        state = CAN_TXSTATE_FAILED;
        break;
    /* transmit succeeded  */
    case (CAN_TSTR_MTF0 | CAN_TSTR_MTFNE0 | CAN_TSTR_TME0):
        state = CAN_TXSTATE_OK;
        break;
    case (CAN_TSTR_MTF1 | CAN_TSTR_MTFNE1 | CAN_TSTR_TME1):
        state = CAN_TXSTATE_OK;
        break;
    case (CAN_TSTR_MTF2 | CAN_TSTR_MTFNE2 | CAN_TSTR_TME2):
        state = CAN_TXSTATE_OK;
        break;
    default:
        state = CAN_TXSTATE_FAILED;
        break;
    }
    return (uint8_t) state;
}

/**
  * @brief  Stop a transmit mission.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  Mailbox:  Mailbox number.
  * @retval None.
  */
void CAN_StopTransmit(CAN_TypeDef *CANx, uint8_t Mailbox)
{
    /* Stop transmission */
    switch (Mailbox) {
    case (CAN_TXMAILBOX_0):
        CANx->TSTR |= CAN_TSTR_MST0;
        break;
    case (CAN_TXMAILBOX_1):
        CANx->TSTR |= CAN_TSTR_MST1;
        break;
    case (CAN_TXMAILBOX_2):
        CANx->TSTR |= CAN_TSTR_MST2;
        break;
    default:
        break;
    }
}

/**
  * @brief  Receive a message.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
  * @param  RxMessage: a structure receive message which contains
  *                    CAN Id, CAN DLC, CAN datas and FI number.
  * @retval None.
  */
void CAN_Receive(CAN_TypeDef *CANx, uint8_t FIFONumber, CanRxMessage *RxMessage)
{
    /* Get the frame identifier */
    RxMessage->FF = (uint8_t)0x04 & CANx->FIFOMailBox[FIFONumber].RFMIR;
    if (RxMessage->FF == CAN_FF_STANDARD) {
        RxMessage->StdId = CAN_TMIR_StdId_Mask & (CANx->FIFOMailBox[FIFONumber].RFMIR >> 21);
    } else {
        RxMessage->ExtId = CAN_TMIR_ExtId_Mask & (CANx->FIFOMailBox[FIFONumber].RFMIR >> 3);
    }

    RxMessage->FT = (uint8_t)0x02 & CANx->FIFOMailBox[FIFONumber].RFMIR;
    /* Get the data length code */
    RxMessage->DLC = (uint8_t)0x0F & CANx->FIFOMailBox[FIFONumber].RFMPR;
    /* Get the filtering index */
    RxMessage->FI = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMPR >> 8);
    /* Get FIFO mailbox data */
    RxMessage->Data[0] = (uint8_t)0xFF & CANx->FIFOMailBox[FIFONumber].RFMD0R;
    RxMessage->Data[1] = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMD0R >> 8);
    RxMessage->Data[2] = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMD0R >> 16);
    RxMessage->Data[3] = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMD0R >> 24);
    RxMessage->Data[4] = (uint8_t)0xFF & CANx->FIFOMailBox[FIFONumber].RFMD1R;
    RxMessage->Data[5] = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMD1R >> 8);
    RxMessage->Data[6] = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMD1R >> 16);
    RxMessage->Data[7] = (uint8_t)0xFF & (CANx->FIFOMailBox[FIFONumber].RFMD1R >> 24);
    /* Release the FIFO */
    if (FIFONumber == CAN_FIFO0) {
        CANx->RFR0 |= CAN_RFR0_RFD0;
    }

    /* FIFONumber == CAN_FIFO1 */
    else {
        CANx->RFR1 |= CAN_RFR1_RFD1;
    }
}

/**
  * @brief  Dequeue the FIFO.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  FIFONumber: FIFO to dequeue, it can be CAN_FIFO0 or CAN_FIFO1.
  * @retval None.
  */
void CAN_FIFODequeue(CAN_TypeDef *CANx, uint8_t FIFONumber)
{

    if (FIFONumber == CAN_FIFO0) {
        /* Release FIFO 0 */
        CANx->RFR0 |= CAN_RFR0_RFD0;
    } else { /* FIFONumber == CAN_FIFO1 */
        /* Release FIFO1 */
        CANx->RFR1 |= CAN_RFR1_RFD1;
    }
}

/**
  * @brief  Return the length of receiving messages.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  FIFONumber: Receive FIFO number, CAN_FIFO0 or CAN_FIFO1.
  * @retval message_length : which is the Length of pending message.
  */
uint8_t CAN_MessageLength(CAN_TypeDef *CANx, uint8_t FIFONumber)
{
    uint8_t message_length = 0;
    if (FIFONumber == CAN_FIFO0) {
        message_length = (uint8_t)(CANx->RFR0 & (uint32_t)0x03);
    } else if (FIFONumber == CAN_FIFO1) {
        message_length = (uint8_t)(CANx->RFR1 & (uint32_t)0x03);
    } else {
        message_length = 0;
    }
    return message_length;
}

/**
  * @brief   Select the CAN Working mode.
  * @param CAN_WorkingMode : CAN Working Mode.It can be the following one.
  *     @arg CAN_WORKINGMODE_INITIAL
  *     @arg CAN_WORKINGMODE_NORMAL
  *     @arg CAN_WORKINGMODE_SLEEP
  * @retval state of the requested mode which can be
  *     @arg CAN_MODESTATE_FAILED
  *     @arg CAN_MODESTATE_SUCCESS
  */
uint8_t CAN_WorkingMode(CAN_TypeDef *CANx, uint8_t CAN_WorkingMode)
{
    uint8_t state = CAN_MODESTATE_FAILED;

    /* Timeout for IWS or also for SWS bits*/
    uint32_t timeout = IWS_TIMEOUT;

    if (CAN_WorkingMode == CAN_WORKINGMODE_INITIAL) {
        /* Set initialisation */
        CANx->CTLR = (uint32_t)((CANx->CTLR & (uint32_t)(~(uint32_t)CAN_CTLR_SWM)) | CAN_CTLR_IWM);

        /* Wait the acknowledge */
        while (((CANx->STR & CAN_MODE_MASK) != CAN_STR_IWS) && (timeout != 0)) {
            timeout--;
        }
        if ((CANx->STR & CAN_MODE_MASK) != CAN_STR_IWS) {
            state = CAN_MODESTATE_FAILED;
        } else {
            state = CAN_MODESTATE_SUCCESS;
        }
    } else  if (CAN_WorkingMode == CAN_WORKINGMODE_NORMAL) {
        /* Enter Normal mode */
        CANx->CTLR &= (uint32_t)(~(CAN_CTLR_SWM | CAN_CTLR_IWM));

        /* Wait the acknowledge */
        while (((CANx->STR & CAN_MODE_MASK) != 0) && (timeout != 0)) {
            timeout--;
        }
        if ((CANx->STR & CAN_MODE_MASK) != 0) {
            state = CAN_MODESTATE_FAILED;
        } else {
            state = CAN_MODESTATE_SUCCESS;
        }
    } else  if (CAN_WorkingMode == CAN_WORKINGMODE_SLEEP) {
        /* Set Sleep mode */
        CANx->CTLR = (uint32_t)((CANx->CTLR & (uint32_t)(~(uint32_t)CAN_CTLR_IWM)) | CAN_CTLR_SWM);

        /* Wait the acknowledge */
        while (((CANx->STR & CAN_MODE_MASK) != CAN_STR_SWS) && (timeout != 0)) {
            timeout--;
        }
        if ((CANx->STR & CAN_MODE_MASK) != CAN_STR_SWS) {
            state = CAN_MODESTATE_FAILED;
        } else {
            state = CAN_MODESTATE_SUCCESS;
        }
    } else {
        state = CAN_MODESTATE_FAILED;
    }

    return (uint8_t) state;
}

/**
  * @brief  Enter the Sleep mode.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @retval state: CAN_SLEEP_OK or CAN_SLEEP_FAILED.
  */
uint8_t CAN_EnterSleep(CAN_TypeDef *CANx)
{
    /* Set Sleep mode */
    CANx->CTLR = (((CANx->CTLR) & (uint32_t)(~(uint32_t)CAN_CTLR_IWM)) | CAN_CTLR_SWM);

    if ((CANx->STR & (CAN_STR_SWS | CAN_STR_IWS)) == CAN_STR_SWS) {
        /* Sleep mode entered success*/
        return (uint8_t)CAN_SLEEP_OK;
    } else {
        /* Sleep mode entered failure */
        return (uint8_t)CAN_SLEEP_FAILED;
    }
}

/**
  * @brief  Wake up CAN.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @retval status:  CAN_WAKEUP_OK or CAN_WAKEUP_FAILED.
  */
uint8_t CAN_WakeUp(CAN_TypeDef *CANx)
{
    uint32_t wait_sws = SWS_TIMEOUT;

    /*set wake up */
    CANx->CTLR &= ~(uint32_t)CAN_CTLR_SWM;

    /* Sleep mode state */
    while (((CANx->CTLR & CAN_CTLR_SWM) == CAN_CTLR_SWM) && (wait_sws != 0x00)) {
        wait_sws--;
    }
    if ((CANx->CTLR & CAN_CTLR_SWM) != CAN_CTLR_SWM) {
        /*Sleep mode exited */
        return (uint8_t)CAN_WAKEUP_OK;
    } else {
        /*Sleep mode exited failure */
        return (uint8_t)CAN_WAKEUP_FAILED;
    }
}

/**
  * @brief  Return the CANx's last error type (LEC).
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @retval CAN_ErrorType: specify the Error type:
  *     @arg CAN_ERRORTYPE_NOERR
  *     @arg CAN_ERRORTYPE_STUFFERR
  *     @arg CAN_ERRORTYPE_FORMERR
  *     @arg CAN_ERRORTYPE_ACKERR
  *     @arg CAN_ERRORTYPE_BITRECESSIVEERR
  *     @arg CAN_ERRORTYPE_BITDOMINANTERR
  *     @arg CAN_ERRORTYPE_CRCERR
  *     @arg CAN_ERRORTYPE_SOFTWARESETERR
  */

uint8_t CAN_GetErrorType(CAN_TypeDef *CANx)
{
    uint8_t error_type = 0;

    /* Get the error type*/
    error_type = (((uint8_t)CANx->ER) & (uint8_t)CAN_ER_ET);

    /* Return the error type*/
    return error_type;
}

/**
  * @brief  Get the Counter of CANx Receive Error(REC).
  * @note   According to the error condition as defined by the CAN standard,
  *         the counter of CANx Receive Error is increased by 1 or by 8.
  *         When CAN received success everytime, the counter is decreased by 1
  *         or reset to 120 if its value was over than 128.
  *         When the counter value is over 127, the CAN controller enters the
  *         error passive state.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @retval CAN Receive Error Counter.
  */
uint8_t CAN_GetReceiveErrorCounter(CAN_TypeDef *CANx)
{
    uint8_t receive_counter = 0;

    /* Get the counter of CANx Receive Error*/
    receive_counter = (uint8_t)((CANx->ER & CAN_ER_REC) >> 24);

    /* Return the Receive Error Counter*/
    return receive_counter;
}

/**
  * @brief  Get the Counter of CANx Transmit Error (TEC).
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @retval CAN Transmit Error Counter.
  */
uint8_t CAN_GetTransmitErrorCounter(CAN_TypeDef *CANx)
{
    uint8_t transmit_counter = 0;

    /* Get the Counter of CANx Transmit Error(TEC) */
    transmit_counter = (uint8_t)((CANx->ER & CAN_ER_TEC) >> 16);

    /* Return the Transmit Error Counter*/
    return transmit_counter;
}

/**
  * @brief  Enable or disable the specified CANx interrupts.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  CAN_INT: specify the CAN interrupt sources to be enabled or disabled.
  *   This parameter can be:
  *     @arg CAN_INT_TME
  *     @arg CAN_INT_RFNE0
  *     @arg CAN_INT_RFF0
  *     @arg CAN_INT_RFO0
  *     @arg CAN_INT_RFNE1
  *     @arg CAN_INT_RFF1
  *     @arg CAN_INT_RFO1
  *     @arg CAN_INT_WE
  *     @arg CAN_INT_PE
  *     @arg CAN_INT_BOE
  *     @arg CAN_INT_ET
  *     @arg CAN_INT_ERR
  *     @arg CAN_INT_WU
  *     @arg CAN_INT_SLP
  * @param  NewValue: new state of the CAN interrupts.
  *                   This parameter can be: ENABLE or DISABLE.
  * @retval None.
  */
void CAN_INTConfig(CAN_TypeDef *CANx, uint32_t CAN_INT, TypeState NewValue)
{
    if (NewValue != DISABLE) {
        /* Enable interrupt */
        CANx->IER |= CAN_INT;
    } else {
        /* Disable interrupt */
        CANx->IER &= ~CAN_INT;
    }
}
/**
  * @brief  Check whether the specified CAN flag is set or not.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  CAN_FLAG: specify the flag to check.
  *   This parameter can be one of the following flags:
  *     @arg CAN_FLAG_WE:   Warning error Flag
  *     @arg CAN_FLAG_PE:   Passive error Flag
  *     @arg CAN_FLAG_BOE:  Bus-off error Flag
  *     @arg CAN_FLAG_MTF0: Mailbox 0 transmit finished Flag
  *     @arg CAN_FLAG_MTF1: Mailbox 1 transmit finished Flag
  *     @arg CAN_FLAG_MTF2: Mailbox 2 transmit finished Flag
  *     @arg CAN_FLAG_RFL0: the length of the receive FIFO0 Flag
  *     @arg CAN_FLAG_RFF0: Receive FIFO 0 full Flag
  *     @arg CAN_FLAG_RFO0: Receive FIFO 0 overfull  Flag
  *     @arg CAN_FLAG_RFL1: the length of the receive FIFO1 Flag
  *     @arg CAN_FLAG_RFF1: Receive FIFO 1 full Flag
  *     @arg CAN_FLAG_RFO1: Receive FIFO 0 overfull  Flag
  *     @arg CAN_FLAG_WU:   Wake up Flag
  *     @arg CAN_FLAG_SLP:  Sleep working state Flag
  *     @arg CAN_FLAG_ET:   Error type Flag
  * @retval The new state of CAN_FLAG (SET or RESET).
  */
TypeState CAN_GetBitState(CAN_TypeDef *CANx, uint32_t CAN_FLAG)
{
    if ((CAN_FLAG & CAN_FLAGS_ER) != (uint32_t)RESET) {
        /* Check the state of the specified CAN flag */
        if ((CANx->ER & (CAN_FLAG & CAN_FLAG_Mask)) != (uint32_t)RESET) {
            /* CAN_FLAG is set */
            return SET;
        } else {
            /* CAN_FLAG is reset */
            return RESET;
        }
    } else if ((CAN_FLAG & CAN_FLAGS_STR) != (uint32_t)RESET) {
        /* Check the state of the specified CAN flag */
        if ((CANx->STR & (CAN_FLAG & CAN_FLAG_Mask)) != (uint32_t)RESET) {
            /* CAN_FLAG is set */
            return SET;
        } else {
            /* CAN_FLAG is reset */
            return RESET;
        }
    } else if ((CAN_FLAG & CAN_FLAGS_TSTR) != (uint32_t)RESET) {
        /* Check the state of the specified CAN flag */
        if ((CANx->TSTR & (CAN_FLAG & CAN_FLAG_Mask)) != (uint32_t)RESET) {
            /* CAN_FLAG is set */
            return SET;
        } else {
            /* CAN_FLAG is reset */
            return RESET;
        }
    } else if ((CAN_FLAG & CAN_FLAGS_RFR0) != (uint32_t)RESET) {
        /* Check the state of the specified CAN flag */
        if ((CANx->RFR0 & (CAN_FLAG & CAN_FLAG_Mask)) != (uint32_t)RESET) {
            /* CAN_FLAG is set */
            return SET;
        } else {
            /* CAN_FLAG is reset */
            return RESET;
        }
    }
    /* If(CAN_FLAG & CAN_FLAGS_RFR1 != (uint32_t)RESET) */
    else {
        /* Check the state of the specified CAN flag */
        if ((uint32_t)(CANx->RFR1 & (CAN_FLAG & CAN_FLAG_Mask)) != (uint32_t)RESET) {
            /* CAN_FLAG is set */
            return SET;
        } else {
            /* CAN_FLAG is reset */
            return RESET;
        }
    }
}

/**
  * @brief  Clear the CAN's flags.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  CAN_FLAG: specify the flag to clear.
  *   This parameter can be one of the following flags:
  *     @arg CAN_FLAG_MTF0: Mailbox 0 transmit finished Flag
  *     @arg CAN_FLAG_MTF1: Mailbox 1 transmit finished Flag
  *     @arg CAN_FLAG_MTF2: Mailbox 2 transmit finished Flag
  *     @arg CAN_FLAG_RFF0: Receive FIFO 0 full Flag
  *     @arg CAN_FLAG_RFO0: Receive FIFO 0 overfull  Flag
  *     @arg CAN_FLAG_RFF1: Receive FIFO 1 full Flag
  *     @arg CAN_FLAG_RFO1: Receive FIFO 0 overfull  Flag
  *     @arg CAN_FLAG_WU:   Wake up Flag
  *     @arg CAN_FLAG_SLP:  Sleep working state Flag
  *     @arg CAN_FLAG_ET:   Error type Flag
  * @retval None.
  */
void CAN_ClearBitState(CAN_TypeDef *CANx, uint32_t CAN_FLAG)
{
    uint32_t temp = 0;

    /* ER register */
    if (CAN_FLAG == CAN_FLAG_ET) {
        /* Clear the selected CAN flags */
        CANx->ER = (uint32_t)RESET;
    }
    /* STR or TSTR or RFR0 or RFR1 */
    else {
        temp = CAN_FLAG & CAN_FLAG_Mask;

        if ((CAN_FLAG & CAN_FLAGS_RFR0) != (uint32_t)RESET) {
            /* Receive Flags */
            CANx->RFR0 = (uint32_t)(temp);
        } else if ((CAN_FLAG & CAN_FLAGS_RFR1) != (uint32_t)RESET) {
            /* Receive Flags */
            CANx->RFR1 = (uint32_t)(temp);
        } else if ((CAN_FLAG & CAN_FLAGS_TSTR) != (uint32_t)RESET) {
            /* Transmit Flags */
            CANx->TSTR = (uint32_t)(temp);
        }
        /* If((CAN_FLAG & CAN_FLAGS_STR)!=(uint32_t)RESET) */
        else {
            CANx->STR = (uint32_t)(temp);
        }
    }
}

/**
  * @brief  Check whether the specified CANx interrupt has occurred or not.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  CAN_INT:  specify the CAN interrupt source to check.
  *   This parameter can be:
  *     @arg CAN_INT_TME
  *     @arg CAN_INT_RFNE0
  *     @arg CAN_INT_RFF0
  *     @arg CAN_INT_RFO0
  *     @arg CAN_INT_RFNE1
  *     @arg CAN_INT_RFF1
  *     @arg CAN_INT_RFO1
  *     @arg CAN_INT_WE
  *     @arg CAN_INT_PE
  *     @arg CAN_INT_BOE
  *     @arg CAN_INT_ET
  *     @arg CAN_INT_ERR
  *     @arg CAN_INT_WU
  *     @arg CAN_INT_SLP
  * @retval The current state of CAN_INT (SET or RESET).
  */
TypeState CAN_GetIntBitState(CAN_TypeDef *CANx, uint32_t CAN_INT)
{
    TypeState intstate = RESET;

    /* Get the enable interrupt bit */
    if ((CANx->IER & CAN_INT) != RESET) {
        switch (CAN_INT) {
        case CAN_INT_TME:
            /* Check CAN_TSTR_MTFx bits */
            intstate = CheckINTState(CANx->TSTR, CAN_TSTR_MTF0 | CAN_TSTR_MTF1 | CAN_TSTR_MTF2);
            break;
        case CAN_INT_RFNE0:
            /* Check CAN_RFR0_RFL0 bit */
            intstate = CheckINTState(CANx->RFR0, CAN_RFR0_RFL0);
            break;
        case CAN_INT_RFF0:
            /* Check CAN_RFR0_RFF0 bit */
            intstate = CheckINTState(CANx->RFR0, CAN_RFR0_RFF0);
            break;
        case CAN_INT_RFO0:
            /* Check CAN_RFR0_RFO0 bit */
            intstate = CheckINTState(CANx->RFR0, CAN_RFR0_RFO0);
            break;
        case CAN_INT_RFNE1:
            /* Check CAN_RFR1_RFL1 bit */
            intstate = CheckINTState(CANx->RFR1, CAN_RFR1_RFL1);
            break;
        case CAN_INT_RFF1:
            /* Check CAN_RFR1_RFF1 bit */
            intstate = CheckINTState(CANx->RFR1, CAN_RFR1_RFF1);
            break;
        case CAN_INT_RFO1:
            /* Check CAN_RFR1_RFO1 bit */
            intstate = CheckINTState(CANx->RFR1, CAN_RFR1_RFO1);
            break;
        case CAN_INT_WU:
            /* Check CAN_STR_WIF bit */
            intstate = CheckINTState(CANx->STR, CAN_STR_WIF);
            break;
        case CAN_INT_SLP:
            /* Check CAN_STR_SEIF bit */
            intstate = CheckINTState(CANx->STR, CAN_STR_SEIF);
            break;
        case CAN_INT_WE:
            /* Check CAN_INT_WE bit */
            intstate = CheckINTState(CANx->ER, CAN_ER_WE);
            break;
        case CAN_INT_PE:
            /* Check CAN_INT_EP bit */
            intstate = CheckINTState(CANx->ER, CAN_ER_PE);
            break;
        case CAN_INT_BOE:
            /* Check CAN_ER_BOE bit */
            intstate = CheckINTState(CANx->ER, CAN_ER_BOE);
            break;
        case CAN_INT_ET:
            /* Check CAN_ER_ET bit */
            intstate = CheckINTState(CANx->ER, CAN_ER_ET);
            break;
        case CAN_INT_ERR:
            /* Check CAN_STR_EIF bit */
            intstate = CheckINTState(CANx->STR, CAN_STR_EIF);
            break;
        default :
            /* in case of error, return RESET */
            intstate = RESET;
            break;
        }
    } else {
        /* in case the Interrupt is not enabled, return RESET */
        intstate  = RESET;
    }

    /* Return the CAN_INT status */
    return  intstate;
}

/**
  * @brief  Clear the CANx's interrupt pending bits.
  * @param  CANx: where x:[1,2] to to select the CAN peripheral.
  * @param  CAN_INT: specify the interrupt pending bit to clear.
  *   This parameter can be:
  *     @arg CAN_INT_TME
  *     @arg CAN_INT_RFF0
  *     @arg CAN_INT_RFO0
  *     @arg CAN_INT_RFF1
  *     @arg CAN_INT_RFO1
  *     @arg CAN_INT_WE
  *     @arg CAN_INT_PE
  *     @arg CAN_INT_BOE
  *     @arg CAN_INT_ET
  *     @arg CAN_INT_ERR
  *     @arg CAN_INT_WU
  *     @arg CAN_INT_SLP
  * @retval None.
  */
void CAN_ClearIntBitState(CAN_TypeDef *CANx, uint32_t CAN_INT)
{
    switch (CAN_INT) {
    case CAN_INT_TME:
        /* Clear CAN_TSTR_MTFx (rc_w1)*/
        CANx->TSTR = CAN_TSTR_MTF0 | CAN_TSTR_MTF1 | CAN_TSTR_MTF2;
        break;
    case CAN_INT_RFF0:
        /* Clear CAN_RFR0_RFF0 (rc_w1)*/
        CANx->RFR0 = CAN_RFR0_RFF0;
        break;
    case CAN_INT_RFO0:
        /* Clear CAN_RFR0_RFO0 (rc_w1)*/
        CANx->RFR0 = CAN_RFR0_RFO0;
        break;
    case CAN_INT_RFF1:
        /* Clear CAN_RFR1_RFF1 (rc_w1)*/
        CANx->RFR1 = CAN_RFR1_RFF1;
        break;
    case CAN_INT_RFO1:
        /* Clear CAN_RFR1_RFO1 (rc_w1)*/
        CANx->RFR1 = CAN_RFR1_RFO1;
        break;
    case CAN_INT_WU:
        /* Clear CAN_STR_WIF (rc_w1)*/
        CANx->STR = CAN_STR_WIF;
        break;
    case CAN_INT_SLP:
        /* Clear CAN_STR_SEIF (rc_w1)*/
        CANx->STR = CAN_STR_SEIF;
        break;
    case CAN_INT_WE:
        /* Clear CAN_STR_EIF (rc_w1) */
        CANx->STR = CAN_STR_EIF;
        break;
    case CAN_INT_PE:
        /* Clear CAN_MSR_ERRI (rc_w1) */
        CANx->STR = CAN_STR_EIF;
        break;
    case CAN_INT_BOE:
        /* Clear CAN_STR_EIF (rc_w1) */
        CANx->STR = CAN_STR_EIF;
        break;
    case CAN_INT_ET:
        /*  Clear ET bits */
        CANx->ER = RESET;
        /* Clear CAN_STR_EIF (rc_w1) */
        CANx->STR = CAN_STR_EIF;
        break;
    case CAN_INT_ERR:
        /*Clear ET bits */
        CANx->ER = RESET;
        /* Clear CAN_STR_EIF (rc_w1) */
        CANx->STR = CAN_STR_EIF;
        break;
    default :
        break;
    }
}

/**
  * @brief  Check whether the CAN interrupt has occurred or not.
  * @param  CAN_Reg: the register of CAN interrupt to check.
  * @param  Int_Bit: the bit of interrupt source to check.
  * @retval The new state of the CAN Interrupt (SET or RESET).
  */
static TypeState CheckINTState(uint32_t CAN_Reg, uint32_t Int_Bit)
{
    if ((CAN_Reg & Int_Bit) != (uint32_t)RESET) {
        /* CAN_INT is set */
        return SET;
    } else {
        /* CAN_IT is reset */
        return RESET;
    }
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */


text:
// Copyright (c)  Zhirnov Andrey. For more information see 'LICENSE.txt'

#pragma once

#include "Core/STL/Containers/Array.h"
#include "Core/STL/Containers/IndexedIterator.h"

namespace GX_STL
{
namespace GXTypes
{

	#define RET_ERROR( _ret_ )	{ WARNING("error in CircularQueue");  return _ret_; }
	#define RET_FALSE			RET_ERROR( false )
	#define RET_VOID			RET_ERROR( ; )

	//
	// Circular Queue
	//

	template <	typename T,
				typename S = typename AutoDetectCopyStrategy<T>::type,
				typename MC = MemoryContainer<T>
			 >
	struct CircularQueue : public CompileTime::CopyQualifiers< CompileTime::FastCopyable, MC >
	{
	// types
	public:
		using Strategy_t		= S;
		using MemoryContainer_t	= MC;
		using Value_t			= T;
		using Self				= CircularQueue<T,S,MC>;
		using iterator			= IndexedIterator<T>;
		using const_iterator	= IndexedIterator<const T>;

	// variables
	private:
		MemoryContainer_t	_memory;
		usize				_first,
							_end,		// last + 1
							_size;

		//  _____________ __________ _____________
		// | used memory | reserved | used memory |
		// 0           _end      _first        _size

	// methods
	private:
		void  _Reallocate (usize newSize, bool allowReserve);
		usize _WrapIndex (isize i) const;
		void  _Move (Self &&other);

		template <typename B>
		void _AppendFront (B* pArray, usize count);

		template <typename B>
		void _AppendBack (B* pArray, usize count);

		static bool  _CheckIntersection (const void *leftBegin, const void *leftEnd,
										 const void *rightBegin, const void *rightEnd);

	public:
		CircularQueue (GX_DEFCTOR);

		CircularQueue (const Self &other);

		CircularQueue (Self &&other);

		CircularQueue (ArrayCRef<T> other);

		~CircularQueue ()												{ Free(); }

		ND_ T		&	Front ();
		ND_ T const	&	Front () const;

		ND_ T		&	Back ();
		ND_ T const	&	Back () const;

		ND_ T		&	operator [] (usize i);
		ND_ T const	&	operator [] (usize i) const;

			Self &		operator =  (ArrayCRef<T> right)				{ Copy( right );					return *this; }
			Self &		operator =  (const Self &right)					{ Copy( right );					return *this; }
			Self &		operator =  (Self &&right)						{ Free();  _Move( RVREF(right) );	return *this; }

			Self &		operator << (const T& right)					{ PushBack( right );				return *this; }
			Self &		operator << (Self &&right)						{ AppendBack( RVREF( right ) );		return *this; }
			Self &		operator << (const Self &right)					{ AppendBack( right );				return *this; }
			Self &		operator << (ArrayCRef<T> right)				{ AppendBack( right );				return *this; }

		friend Self &	operator >> (const T& left, Self &right)		{ right.PushFront( left );				return right; }
		friend Self &	operator >> (Self &&left, Self &right)			{ right.AppendFront( RVREF( left ) );	return right; }
		friend Self &	operator >> (const Self &left, Self &right)		{ right.AppendFront( left );			return right; }
		friend Self &	operator >> (ArrayCRef<T> left, Self &right)	{ right.AppendFront( left );			return right; }

		ND_ bool		operator == (ArrayCRef<T> right)	const;
		ND_ bool		operator == (const Self &right)		const;
		ND_ bool		operator != (ArrayCRef<T> right)	const		{ return not ( (*this) == right ); }
		ND_ bool		operator != (const Self &right)		const		{ return not ( (*this) == right ); }

		void PushBack (const T &value);
		void PushBack (T&& value);

		void PushFront (const T &value);
		void PushFront (T&& value);

		void PopBack ();
		void PopFront ();

		void AppendFront (ArrayCRef<T> value);
		void AppendFront (const Self &value);
		void AppendFront (Self &&value);

		void AppendBack (ArrayCRef<T> value);
		void AppendBack (const Self &value);
		void AppendBack (Self &&value);

		void Copy (ArrayCRef<T> other);
		void Copy (const Self &other);

		void Resize (usize newSize, bool allowReserve = true);
		void Reserve (usize size);

		void Free ();
		void Clear ();

		void GetParts (OUT ArrayRef<T> &part0, OUT ArrayRef<T> &part1);
		void GetParts (OUT ArrayCRef<T> &part0, OUT ArrayCRef<T> &part1) const;

		ND_ usize			Count ()		const;
		ND_ BytesU			Size ()			const				{ return SizeOf<T> * Count(); }
		ND_ usize			Capacity ()		const				{ return _size-1; }
		ND_ constexpr usize MaxCapacity ()	const				{ return _memory.MaxSize(); }	// max available for allocation count of elements
		ND_ BytesU			FullSize ()		const				{ return SizeOf<T> * Capacity(); }
		ND_ bool			Empty ()		const				{ return _first == _end; }
		ND_ usize			LastIndex ()	const				{ return Count()-1; }

		ND_ auto			begin ()							{ return IndexedIterator<T>{ *this, 0 }; }
		ND_ auto			begin ()		const				{ return IndexedIterator<const T>{ *this, 0 }; }
		ND_ auto			end ()								{ return IndexedIterator<T>{ *this, Count() }; }
		ND_ auto			end ()			const				{ return IndexedIterator<const T>{ *this, Count() }; }

		static constexpr bool	IsLinearMemory ()				{ return false; }
		constexpr bool			IsStaticMemory ()	const		{ return _memory.IsStatic(); }

		friend void SwapValues (INOUT Self &left, INOUT Self &right)
		{
			left._memory.SwapMemory( right._memory );

			SwapValues( left._first,	right._first );
			SwapValues( left._end,		right._end );
			SwapValues( left._size,		right._size );
		}
	};

	template <typename T, usize Size>
	using FixedSizeCircularQueue = CircularQueue< T, typename AutoDetectCopyStrategy<T>::type, StaticMemoryContainer<T, Size> >;

/*
=================================================
	constructor
=================================================
*/
	template <typename T, typename S, typename MC>
	inline CircularQueue<T,S,MC>::CircularQueue (UninitializedType) :
		_first(0), _end(0), _size(0)
	{}

/*
=================================================
	constructor
=================================================
*/
	template <typename T, typename S, typename MC>
	inline CircularQueue<T,S,MC>::CircularQueue (const Self &other) :
		_first(0), _end(0), _size(0)
	{
		Copy( other );
	}

/*
=================================================
	constructor
=================================================
*/
	template <typename T, typename S, typename MC>
	inline CircularQueue<T,S,MC>::CircularQueue (Self &&other)
	{
		_Move( RVREF( other ) );
	}

/*
=================================================
	constructor
=================================================
*/
	template <typename T, typename S, typename MC>
	inline CircularQueue<T,S,MC>::CircularQueue (ArrayCRef<T> other) :
		_first(0), _end(0), _size(0)
	{
		Copy( other );
	}

/*
=================================================
	_Move
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::_Move (Self &&other)
	{
		_memory	= RVREF( other._memory );
		_first	= other._first;
		_end	= other._end;
		_size	= other._size;

		other._first = other._end = other._size = 0;
	}

/*
=================================================
	_Reallocate
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void  CircularQueue<T,S,MC>::_Reallocate (const usize newSize, const bool allowReserve)
	{
		if ( newSize <= _size )
			return;

		// save old values
		const usize			old_size	= _size;
		usize				old_count	= Count();
		MemoryContainer_t	old_memcont;	old_memcont.MoveFrom( INOUT _memory );

		_size = newSize;

		CHECK( _memory.Allocate( INOUT _size, allowReserve ) );
		old_count = GXMath::Min( old_count, _size );

		if ( old_memcont.Pointer() == null or old_count == 0 )
		{
			_first = _end = 0;
			return;
		}

		// replace
		if ( _first > _end )
		{
			usize	off = old_size - _first;
			Strategy_t::Replace( _memory.Pointer(), old_memcont.Pointer() + _first, off );
			Strategy_t::Replace( _memory.Pointer() + off, old_memcont.Pointer(), _end );
		}
		else
		{
			Strategy_t::Replace( _memory.Pointer(), old_memcont.Pointer() + _first, _end - _first );
		}

		_first = 0;
		_end   = old_count;
	}

/*
=================================================
	_CheckIntersection
=================================================
*/
	template <typename T, typename S, typename MC>
	inline bool CircularQueue<T,S,MC>::_CheckIntersection (const void *leftBegin, const void *leftEnd,
															const void *rightBegin, const void *rightEnd)
	{
		return CheckPointersAliasing( leftBegin, leftEnd, rightBegin, rightEnd );
	}

/*
=================================================
	_WrapIndex
=================================================
*/
	template <typename T, typename S, typename MC>
	inline usize CircularQueue<T,S,MC>::_WrapIndex (const isize i) const
	{
		return ( i < 0 ? _size + i : ( i >= isize(_size) ? i - _size : i ) );
	}

/*
=================================================
	Count
=================================================
*/
	template <typename T, typename S, typename MC>
	inline usize  CircularQueue<T,S,MC>::Count () const
	{
		return	_first <= _end ?
				( _end - _first ) :
				( _size - _first + _end );
	}

/*
=================================================
	Front
=================================================
*/
	template <typename T, typename S, typename MC>
	inline T & CircularQueue<T,S,MC>::Front ()
	{
		ASSERT( not Empty() );
		return _memory.Pointer()[ _first ];
	}

	template <typename T, typename S, typename MC>
	inline T const & CircularQueue<T,S,MC>::Front () const
	{
		ASSERT( not Empty() );
		return _memory.Pointer()[ _first ];
	}

/*
=================================================
	Back
=================================================
*/
	template <typename T, typename S, typename MC>
	inline T & CircularQueue<T,S,MC>::Back ()
	{
		ASSERT( not Empty() );
		return _memory.Pointer()[ _WrapIndex( _end - 1 ) ];
	}

	template <typename T, typename S, typename MC>
	inline T const & CircularQueue<T,S,MC>::Back () const
	{
		ASSERT( not Empty() );
		return _memory.Pointer()[ _WrapIndex( _end - 1 ) ];
	}

/*
=================================================
	operator []
=================================================
*/
	template <typename T, typename S, typename MC>
	inline T & CircularQueue<T,S,MC>::operator [] (const usize i)
	{
		ASSERT( i < Count() );
		return _memory.Pointer()[ _WrapIndex( i + _first ) ];
	}

	template <typename T, typename S, typename MC>
	inline T const & CircularQueue<T,S,MC>::operator [] (const usize i) const
	{
		ASSERT( i < Count() );
		return _memory.Pointer()[ _WrapIndex( i + _first ) ];
	}

/*
=================================================
	PushBack
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::PushBack (const T &value)
	{
		usize cnt = Count();

		if ( cnt+2 >= _size )
			_Reallocate( _size+1, true );

		Strategy_t::Copy( _memory.Pointer() + _end, AddressOf(value), 1 );
		_end = _WrapIndex( _end + 1 );
	}

/*
=================================================
	PushBack
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::PushBack (T&& value)
	{
		if ( Count()+2 >= _size )
			_Reallocate( _size+1, true );

		Strategy_t::Move( _memory.Pointer() + _end, AddressOf(value), 1 );
		_end = _WrapIndex( _end + 1 );
	}

/*
=================================================
	PushFront
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::PushFront (const T &value)
	{
		if ( Count()+2 >= _size )
			_Reallocate( _size+1, true );

		_first = _WrapIndex( _first - 1 );
		Strategy_t::Copy( _memory.Pointer() + _first, AddressOf(value), 1 );
	}

/*
=================================================
	PushFront
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::PushFront (T&& value)
	{
		if ( Count()+2 >= _size )
			_Reallocate( _size+1, true );

		_first = _WrapIndex( _first - 1 );
		Strategy_t::Move( _memory.Pointer() + _first, AddressOf(value), 1 );
	}

/*
=================================================
	PopBack
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::PopBack ()
	{
		if ( not Empty() )
		{
			_end = _WrapIndex( _end - 1 );
			Strategy_t::Destroy( _memory.Pointer() + _end, 1 );
		}
	}

/*
=================================================
	PopFront
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::PopFront ()
	{
		if ( not Empty() )
		{
			Strategy_t::Destroy( _memory.Pointer() + _first, 1 );
			_first = _WrapIndex( _first + 1 );
		}
	}

/*
=================================================
	_AppendFront
=================================================
*/
	template <typename T, typename S, typename MC>
	template <typename B>
	inline void CircularQueue<T,S,MC>::_AppendFront (B *pArray, const usize count)
	{
		if ( pArray == null or count == 0 )
			return;

		if ( not Empty() and _CheckIntersection( _memory.Pointer(), _memory.Pointer() + _size, pArray, pArray + count ) )
			RET_VOID;

		if ( Count() + count + 1 >= _size )
			_Reallocate( _size + count + 1, true );

		if ( Empty() )
		{
			if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer(), pArray, count );
			else									Strategy_t::Move( _memory.Pointer(), const_cast<T*>(pArray), count );

			_first = 0;
			_end   = count;
		}
		else
		if ( _first < _end )
		{
			const usize	cnt = GXMath::Min( count, _first );

			if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer() + _first - cnt, pArray + count - cnt, cnt );
			else									Strategy_t::Move( _memory.Pointer() + _first - cnt, const_cast<T*>(pArray) + count - cnt, cnt );

			_first -= cnt;

			if ( cnt != count )
			{
				_first = _size - (count - cnt);

				if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer() + _first, pArray, count - cnt );
				else									Strategy_t::Move( _memory.Pointer() + _first, const_cast<T*>(pArray), count - cnt );
			}
		}
		else
		{
			if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer() + _first - count, pArray, count );
			else									Strategy_t::Move( _memory.Pointer() + _first - count, const_cast<T*>(pArray), count );

			_first -= count;
		}
	}

/*
=================================================
	_AppendBack
=================================================
*/
	template <typename T, typename S, typename MC>
	template <typename B>
	inline void CircularQueue<T,S,MC>::_AppendBack (B *pArray, const usize count)
	{
		if ( pArray == null or count == 0 )
			return;

		if ( not Empty() and _CheckIntersection( _memory.Pointer(), _memory.Pointer() + _size, pArray, pArray + count ) )
			RET_VOID;

		if ( Count() + count + 1 >= _size )
			_Reallocate( _size + count + 1, true );

		if ( Empty() )
		{
			if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer(), pArray, count );
			else									Strategy_t::Move( _memory.Pointer(), const_cast<T*>(pArray), count );

			_first = 0;
			_end   = count;
		}
		else
		if ( _first < _end )
		{
			const usize	cnt = GXMath::Min( count, _size - _end );

			if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer() + _end, pArray, cnt );
			else									Strategy_t::Move( _memory.Pointer() + _end, const_cast<T*>(pArray), cnt );

			_end += cnt;

			if ( cnt != count )
			{
				_end = count - cnt;

				if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer(), pArray + cnt, count - cnt );
				else									Strategy_t::Move( _memory.Pointer(), const_cast<T*>(pArray) + cnt, count - cnt );
			}
		}
		else
		{
			if_constexpr( TypeTraits::IsConst<B> )	Strategy_t::Copy( _memory.Pointer() + _end, pArray, count );
			else									Strategy_t::Move( _memory.Pointer() + _end, const_cast<T*>(pArray), count );

			_end += count;
		}
	}

/*
=================================================
	AppendFront
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::AppendFront (ArrayCRef<T> value)
	{
		return _AppendFront<const T>( value.RawPtr(), value.Count() );
	}

/*
=================================================
	AppendFront
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::AppendFront (const Self &value)
	{
		ArrayCRef<T>	part0;
		ArrayCRef<T>	part1;
		value.GetParts( part0, part1 );

		AppendFront( part1 );
		AppendFront( part0 );
	}

/*
=================================================
	AppendFront
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::AppendFront (Self &&value)
	{
		ArrayRef<T>	part0;
		ArrayRef<T>	part1;
		value.GetParts( part0, part1 );

		_AppendFront<T>( part1.RawPtr(), part1.Count() );
		_AppendFront<T>( part0.RawPtr(), part0.Count() );
	}

/*
=================================================
	AppendBack
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::AppendBack (ArrayCRef<T> value)
	{
		return _AppendBack<const T>( value.RawPtr(), value.Count() );
	}

/*
=================================================
	AppendBack
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::AppendBack (const Self &value)
	{
		ArrayCRef<T>	part0;
		ArrayCRef<T>	part1;
		value.GetParts( part0, part1 );

		AppendBack( part1 );
		AppendBack( part0 );
	}

/*
=================================================
	AppendBack
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::AppendBack (Self &&value)
	{
		ArrayRef<T>	part0;
		ArrayRef<T>	part1;
		value.GetParts( part0, part1 );

		_AppendBack<T>( part1.RawPtr(), part1.Count() );
		_AppendBack<T>( part0.RawPtr(), part0.Count() );
	}

/*
=================================================
	Reserve
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::Reserve (const usize size)
	{
		if ( size <= _size )
			return;

		_Reallocate( size, false );
	}

/*
=================================================
	Resize
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::Resize (const usize newSize, const bool allowReserve)
	{
		const usize	old_count = Count();

		if ( newSize == old_count )
			return;

		if ( newSize == 0 )
		{
			Clear();
			return;
		}

		if ( newSize < old_count )
		{
			const usize	first_del = _WrapIndex( _first + newSize );

			if ( first_del > _end )
			{
				Strategy_t::Destroy( _memory.Pointer() + first_del, _size - first_del );
				Strategy_t::Destroy( _memory.Pointer(), _end );
			}
			else
			{
				Strategy_t::Destroy( _memory.Pointer() + first_del, old_count - newSize );
			}

			_end = first_del;
			return;
		}

		_Reallocate( newSize, allowReserve );
		_end = _WrapIndex( _first + newSize );

		const usize	first_uninit = _WrapIndex( _first + old_count );

		if ( first_uninit > _end )
		{
			Strategy_t::Create( _memory.Pointer() + first_uninit, _size - first_uninit );
			Strategy_t::Create( _memory.Pointer(), _end );
		}
		else
		{
			Strategy_t::Create( _memory.Pointer() + first_uninit, newSize - old_count );
		}
	}

/*
=================================================
	operator ==
=================================================
*/
	template <typename T, typename S, typename MC>
	inline bool CircularQueue<T,S,MC>::operator == (ArrayCRef<T> right) const
	{
		if ( Count() != right.Count() )
			return false;

		FOR( i, right )
		{
			if ( not ( (*this)[i] == right[i] ) )
				return false;
		}
		return true;
	}

/*
=================================================
	operator ==
=================================================
*/
	template <typename T, typename S, typename MC>
	inline bool CircularQueue<T,S,MC>::operator == (const Self &right) const
	{
		if ( Count() != right.Count() )
			return false;

		FOR( i, right )
		{
			if ( not ( (*this)[i] == right[i] ) )
				return false;
		}
		return true;
	}

/*
=================================================
	Free
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::Free ()
	{
		if ( _memory.Pointer() != null )
		{
			if ( Empty() )
			{}
			else
			if ( _first > _end )
			{
				Strategy_t::Destroy( _memory.Pointer() + _first, _size - _first );
				Strategy_t::Destroy( _memory.Pointer(), _end );
			}
			else
			{
				Strategy_t::Destroy( _memory.Pointer() + _first, _end - _first );
			}
			_memory.Deallocate();
		}
		_first	= _end = 0;
		_size	= 0;
	}

/*
=================================================
	Clear
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::Clear ()
	{
		if ( _memory.Pointer() != null )
		{
			if ( Empty() )
			{}
			else
			if ( _first > _end )
			{
				Strategy_t::Destroy( _memory.Pointer() + _first, _size - _first );
				Strategy_t::Destroy( _memory.Pointer(), _end );
			}
			else
			{
				Strategy_t::Destroy( _memory.Pointer() + _first, Count() );
			}
		}
		_first = _end = 0;
	}

/*
=================================================
	Copy
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::Copy (const Self &other)
	{
		Clear();
		AppendBack( other );
	}

/*
=================================================
	Copy
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::Copy (ArrayCRef<T> other)
	{
		Clear();
		AppendBack( other );
	}

/*
=================================================
	GetParts
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::GetParts (OUT ArrayRef<T> &part0, OUT ArrayRef<T> &part1)
	{
		if ( Empty() )
		{
			part0 = ArrayRef<T>();
			part1 = ArrayRef<T>();
		}
		else
		if ( _first > _end )
		{
			part0 = ArrayRef<T>( _memory.Pointer() + _first, _size - _first );
			part1 = ArrayRef<T>( _memory.Pointer(), _end );
		}
		else
		{
			part0 = ArrayRef<T>( _memory.Pointer() + _first, Count() );
			part1 = ArrayRef<T>();
		}
	}

/*
=================================================
	GetParts
=================================================
*/
	template <typename T, typename S, typename MC>
	inline void CircularQueue<T,S,MC>::GetParts (OUT ArrayCRef<T> &part0, OUT ArrayCRef<T> &part1) const
	{
		if ( Empty() )
		{
			part0 = ArrayCRef<T>();
			part1 = ArrayCRef<T>();
		}
		else
		if ( _first > _end )
		{
			part0 = ArrayCRef<T>( _memory.Pointer() + _first, _size - _first );
			part1 = ArrayCRef<T>( _memory.Pointer(), _end );
		}
		else
		{
			part0 = ArrayCRef<T>( _memory.Pointer() + _first, Count() );
			part1 = ArrayCRef<T>();
		}
	}

	#undef  RET_ERROR
	#undef	RET_FALSE
	#undef  RET_VOID

/*
=================================================
	Hash
=================================================
*/
	template <typename T, typename S, typename MC>
	struct Hash< CircularQueue<T,S,MC> >
	{
		ND_ HashResult  operator () (const CircularQueue<T,S,MC> &x) const noexcept
		{
			ArrayCRef<T>			part0;
			ArrayCRef<T>			part1;
			Hash< ArrayCRef<T> >    hasher;

			x.GetParts( part0, part1 );

			return hasher( part0 ) + hasher( part1 );
		}
	};

}	// GXTypes
}	// GX_STL


text:
#region License

#endregion

using System;
using ObjectGL.Api.Objects.Framebuffers;
using ObjectGL.Api.Objects.Resources.Buffers;
using ObjectGL.Api.Objects.Resources.Images;
using ObjectGL.Api.Objects.Samplers;
using ObjectGL.Api.Objects.Shaders;
using ObjectGL.Api.Objects.TransformFeedbacks;
using ObjectGL.Api.Objects.VertexArrays;

namespace ObjectGL.Api.Context
{
    public interface IContextObjectFactory
    {
        IFramebuffer Framebuffer();
        ISampler Sampler();
        IVertexArray VertexArray();
        IVertexShader VertexShader(string source);
        ITesselationControlShader TesselationControlShader(string source);
        ITesselationEvaluationShader TesselationEvaluationShader(string source);
        IGeometryShader GeometryShader(string source);
        IFragmentShader FragmentShader(string source);
        IShaderProgram Program(ShaderProgramDescription description);
        ITransformFeedback TransformFeedback();
        IBuffer Buffer(BufferTarget creationTarget, int sizeInBytes, BufferUsageHint usage, IntPtr initialData = default(IntPtr));
        IRenderbuffer Renderbuffer(int width, int height, Format internalFormat, int samples = 0);
        ITexture1D Texture1D(int width, int mipCount, Format internalFormat);
        ITexture1DArray Texture1DArray(int width, int sliceCount, int mipCount, Format internalFormat);
        ITexture2D Texture2D(int width, int height, int mipCount, Format internalFormat);
        ITexture2DArray Texture2DArray(int width, int height, int sliceCount, int mipCount, Format internalFormat);
        ITexture2DMultisample Texture2DMultisample(int width, int height, int samples, Format internalFormat, bool fixedSampleLocations = false);
        ITexture2DMultisampleArray Texture2DMultisampleArray(int width, int height, int sliceCount, int samples, Format internalFormat, bool fixedSampleLocations = false);
        ITexture3D Texture3D(int width, int height, int depth, int mipCount, Format internalFormat);
        ITextureCubemap TextureCubemap(int width, int mipCount, Format internalFormat);
        ITextureCubemapArray TextureCubemapArray(int width, int cubeCount, int mipCount, Format internalFormat);
    }
}